Skip to content

Commit

Permalink
HADOOP-19050. S3A: Support S3 Access Grants (#6544)
Browse files Browse the repository at this point in the history
This adds support for Amazon S3 Access Grants to the S3A connector.

For more information, see:
* https://aws.amazon.com/s3/features/access-grants/
* https://github.com/aws/aws-s3-accessgrants-plugin-java-v2/

Contributed by Adnan Hemani
  • Loading branch information
adnanhemani authored Mar 19, 2024
1 parent 705fb83 commit 8b2058a
Show file tree
Hide file tree
Showing 7 changed files with 618 additions and 382 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1624,4 +1624,21 @@ private Constants() {
* Value: {@value}.
*/
public static final boolean DEFAULT_AWS_S3_CLASSLOADER_ISOLATION = true;

/**
* Flag {@value}
* to enable S3 Access Grants to control authorization to S3 data. More information:
* https://aws.amazon.com/s3/features/access-grants/
* and
* https://github.com/aws/aws-s3-accessgrants-plugin-java-v2/
*/
public static final String AWS_S3_ACCESS_GRANTS_ENABLED = "fs.s3a.access.grants.enabled";

/**
* Flag {@value} to enable jobs fall back to the Job Execution IAM role in
* case they get Access Denied from the S3 Access Grants call. More information:
* https://github.com/aws/aws-s3-accessgrants-plugin-java-v2/
*/
public static final String AWS_S3_ACCESS_GRANTS_FALLBACK_TO_IAM_ENABLED =
"fs.s3a.access.grants.fallback.to.iam";
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.s3accessgrants.plugin.S3AccessGrantsPlugin;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.S3BaseClientBuilder;
import software.amazon.awssdk.services.s3.S3Client;
Expand All @@ -53,6 +54,8 @@
import org.apache.hadoop.fs.store.LogExactlyOnce;

import static org.apache.hadoop.fs.s3a.Constants.AWS_REGION;
import static org.apache.hadoop.fs.s3a.Constants.AWS_S3_ACCESS_GRANTS_ENABLED;
import static org.apache.hadoop.fs.s3a.Constants.AWS_S3_ACCESS_GRANTS_FALLBACK_TO_IAM_ENABLED;
import static org.apache.hadoop.fs.s3a.Constants.AWS_S3_DEFAULT_REGION;
import static org.apache.hadoop.fs.s3a.Constants.CENTRAL_ENDPOINT;
import static org.apache.hadoop.fs.s3a.Constants.FIPS_ENDPOINT;
Expand Down Expand Up @@ -112,6 +115,11 @@ public class DefaultS3ClientFactory extends Configured
public static final String ERROR_ENDPOINT_WITH_FIPS =
"Non central endpoint cannot be set when " + FIPS_ENDPOINT + " is true";

/**
* A one-off log stating whether S3 Access Grants are enabled.
*/
private static final LogExactlyOnce LOG_S3AG_ENABLED = new LogExactlyOnce(LOG);

@Override
public S3Client createS3Client(
final URI uri,
Expand Down Expand Up @@ -178,6 +186,8 @@ private <BuilderT extends S3BaseClientBuilder<BuilderT, ClientT>, ClientT> Build

configureEndpointAndRegion(builder, parameters, conf);

maybeApplyS3AccessGrantsConfigurations(builder, conf);

S3Configuration serviceConfiguration = S3Configuration.builder()
.pathStyleAccessEnabled(parameters.isPathStyleAccess())
.checksumValidationEnabled(parameters.isChecksumValidationEnabled())
Expand Down Expand Up @@ -402,4 +412,23 @@ private static Region getS3RegionFromEndpoint(final String endpoint,
return Region.of(AWS_S3_DEFAULT_REGION);
}

private static <BuilderT extends S3BaseClientBuilder<BuilderT, ClientT>, ClientT> void
maybeApplyS3AccessGrantsConfigurations(BuilderT builder, Configuration conf) {
boolean isS3AccessGrantsEnabled = conf.getBoolean(AWS_S3_ACCESS_GRANTS_ENABLED, false);
if (!isS3AccessGrantsEnabled){
LOG.debug("S3 Access Grants plugin is not enabled.");
return;
}

boolean isFallbackEnabled =
conf.getBoolean(AWS_S3_ACCESS_GRANTS_FALLBACK_TO_IAM_ENABLED, false);
S3AccessGrantsPlugin accessGrantsPlugin =
S3AccessGrantsPlugin.builder()
.enableFallback(isFallbackEnabled)
.build();
builder.addPlugin(accessGrantsPlugin);
LOG_S3AG_ENABLED.info(
"S3 Access Grants plugin is enabled with IAM fallback set to {}", isFallbackEnabled);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,11 @@ public class S3AFileSystem extends FileSystem implements StreamCapabilities,
*/
private String configuredRegion;

/**
* Are S3 Access Grants Enabled?
*/
private boolean s3AccessGrantsEnabled;

/** Add any deprecated keys. */
@SuppressWarnings("deprecation")
private static void addDeprecatedKeys() {
Expand Down Expand Up @@ -747,6 +752,7 @@ public void initialize(URI name, Configuration originalConf)
optimizedCopyFromLocal = conf.getBoolean(OPTIMIZED_COPY_FROM_LOCAL,
OPTIMIZED_COPY_FROM_LOCAL_DEFAULT);
LOG.debug("Using optimized copyFromLocal implementation: {}", optimizedCopyFromLocal);
s3AccessGrantsEnabled = conf.getBoolean(AWS_S3_ACCESS_GRANTS_ENABLED, false);
} catch (SdkException e) {
// amazon client exception: stop all services then throw the translation
cleanupWithLogger(LOG, span);
Expand Down Expand Up @@ -5516,6 +5522,10 @@ public boolean hasPathCapability(final Path path, final String capability)
case FIPS_ENDPOINT:
return fipsEnabled;

// is S3 Access Grants enabled
case AWS_S3_ACCESS_GRANTS_ENABLED:
return s3AccessGrantsEnabled;

default:
return super.hasPathCapability(p, cap);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import static org.apache.hadoop.fs.CommonPathCapabilities.FS_CHECKSUMS;
import static org.apache.hadoop.fs.CommonPathCapabilities.FS_MULTIPART_UPLOADER;
import static org.apache.hadoop.fs.Options.OpenFileOptions.FS_OPTION_OPENFILE_STANDARD_OPTIONS;
import static org.apache.hadoop.fs.s3a.Constants.AWS_S3_ACCESS_GRANTS_ENABLED;
import static org.apache.hadoop.fs.s3a.Constants.DIRECTORY_OPERATIONS_PURGE_UPLOADS;
import static org.apache.hadoop.fs.s3a.Constants.ENABLE_MULTI_DELETE;
import static org.apache.hadoop.fs.s3a.Constants.FIPS_ENDPOINT;
Expand Down Expand Up @@ -272,6 +273,7 @@ private InternalConstants() {
FS_MULTIPART_UPLOADER,
DIRECTORY_LISTING_INCONSISTENT,
FIPS_ENDPOINT,
AWS_S3_ACCESS_GRANTS_ENABLED,

// s3 specific
STORE_CAPABILITY_AWS_V2,
Expand Down
Loading

0 comments on commit 8b2058a

Please sign in to comment.