This is an automated email from the ASF dual-hosted git repository.
gaul pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jclouds.git
The following commit(s) were added to refs/heads/master by this push:
new dd6cb51454 JCLOUDS-1644: Create AWS S3 buckets with ownership and
public access block
dd6cb51454 is described below
commit dd6cb514548fe5fe3d1df1cb854dca6207698a64
Author: Andrew Gaul <[email protected]>
AuthorDate: Sun Jan 19 18:50:07 2025 -0800
JCLOUDS-1644: Create AWS S3 buckets with ownership and public access block
AWS changed the defaults when creating buckets to prevent public-read
and other canned ACLs. Background:
https://stackoverflow.com/a/76102067/2800111
---
apis/s3/src/main/java/org/jclouds/s3/S3Client.java | 18 ++++++
.../binders/BindOwnershipControlsToXMLPayload.java | 62 +++++++++++++++++++++
...PublicAccessBlockConfigurationToXMLPayload.java | 65 ++++++++++++++++++++++
.../s3/domain/PublicAccessBlockConfiguration.java | 24 ++++----
.../test/java/org/jclouds/s3/S3ClientLiveTest.java | 9 +++
.../org/jclouds/s3/services/BucketsLiveTest.java | 11 +++-
.../internal/BaseBlobIntegrationTest.java | 5 ++
.../jclouds/aws/s3/blobstore/AWSS3BlobStore.java | 29 ++++++++++
.../org/jclouds/aws/s3/AWSS3ClientLiveTest.java | 8 +++
.../integration/AWSS3BlobIntegrationLiveTest.java | 10 ++++
.../aws/s3/services/AWSBucketsLiveTest.java | 13 ++++-
11 files changed, 237 insertions(+), 17 deletions(-)
diff --git a/apis/s3/src/main/java/org/jclouds/s3/S3Client.java
b/apis/s3/src/main/java/org/jclouds/s3/S3Client.java
index 8dc28d575e..084fa45fb3 100644
--- a/apis/s3/src/main/java/org/jclouds/s3/S3Client.java
+++ b/apis/s3/src/main/java/org/jclouds/s3/S3Client.java
@@ -66,8 +66,10 @@ import org.jclouds.s3.binders.BindCannedAclToRequest;
import org.jclouds.s3.binders.BindIterableAsPayloadToDeleteRequest;
import org.jclouds.s3.binders.BindNoBucketLoggingToXmlPayload;
import org.jclouds.s3.binders.BindObjectMetadataToRequest;
+import org.jclouds.s3.binders.BindOwnershipControlsToXMLPayload;
import org.jclouds.s3.binders.BindPartIdsAndETagsToRequest;
import org.jclouds.s3.binders.BindPayerToXmlPayload;
+import org.jclouds.s3.binders.BindPublicAccessBlockConfigurationToXMLPayload;
import org.jclouds.s3.binders.BindS3ObjectMetadataToRequest;
import org.jclouds.s3.domain.AccessControlList;
import org.jclouds.s3.domain.BucketLogging;
@@ -79,6 +81,7 @@ import org.jclouds.s3.domain.ListMultipartUploadResponse;
import org.jclouds.s3.domain.ListMultipartUploadsResponse;
import org.jclouds.s3.domain.ObjectMetadata;
import org.jclouds.s3.domain.Payer;
+import org.jclouds.s3.domain.PublicAccessBlockConfiguration;
import org.jclouds.s3.domain.S3Object;
import
org.jclouds.s3.fallbacks.FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists;
import org.jclouds.s3.filters.RequestAuthorizeSignature;
@@ -813,4 +816,19 @@ public interface S3Client extends Closeable {
@QueryParam("delimiter") @Nullable String delimiter,
@QueryParam("max-uploads") @Nullable Integer maxUploads,
@QueryParam("key-marker") @Nullable String keyMarker,
@QueryParam("prefix") @Nullable String prefix,
@QueryParam("upload-id-marker") @Nullable String uploadIdMarker);
+
+ @Named("PutBucketOwnershipControls")
+ @PUT
+ @Path("/")
+ @QueryParams(keys = "ownershipControls")
+ void putBucketOwnershipControls(@Bucket @EndpointParam(parser =
AssignCorrectHostnameForBucket.class)
@BinderParam(BindAsHostPrefixIfConfigured.class)
@ParamValidators(BucketNameValidator.class) String bucketName,
+ // BucketOwnerPreferred | ObjectWriter | BucketOwnerEnforced
+ @BinderParam(BindOwnershipControlsToXMLPayload.class) String
objectOwnership);
+
+ @Named("PutPublicAccessBlock")
+ @PUT
+ @Path("/")
+ @QueryParams(keys = "publicAccessBlock")
+ void putPublicAccessBlock(@Bucket @EndpointParam(parser =
AssignCorrectHostnameForBucket.class)
@BinderParam(BindAsHostPrefixIfConfigured.class)
@ParamValidators(BucketNameValidator.class) String bucketName,
+ @BinderParam(BindPublicAccessBlockConfigurationToXMLPayload.class)
PublicAccessBlockConfiguration configuration);
}
diff --git
a/apis/s3/src/main/java/org/jclouds/s3/binders/BindOwnershipControlsToXMLPayload.java
b/apis/s3/src/main/java/org/jclouds/s3/binders/BindOwnershipControlsToXMLPayload.java
new file mode 100644
index 0000000000..59a9f26152
--- /dev/null
+++
b/apis/s3/src/main/java/org/jclouds/s3/binders/BindOwnershipControlsToXMLPayload.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.s3.binders;
+
+import static org.jclouds.s3.binders.XMLHelper.asString;
+import static org.jclouds.s3.binders.XMLHelper.createDocument;
+import static org.jclouds.s3.binders.XMLHelper.elem;
+import static org.jclouds.s3.binders.XMLHelper.elemWithText;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.core.MediaType;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.Binder;
+import org.jclouds.s3.reference.S3Constants;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.google.common.base.Throwables;
+
+@Singleton
+public final class BindOwnershipControlsToXMLPayload implements Binder {
+ @Override
+ public <R extends HttpRequest> R bindToRequest(R request, Object payload) {
+ String from = (String) payload;
+ try {
+ request.setPayload(generatePayload(from));
+
request.getPayload().getContentMetadata().setContentType(MediaType.TEXT_XML);
+ return request;
+ } catch (Exception e) {
+ Throwables.propagateIfPossible(e);
+ throw new RuntimeException("error transforming acl: " + from, e);
+ }
+ }
+
+ protected String generatePayload(String objectOwnership)
+ throws ParserConfigurationException, FactoryConfigurationError,
TransformerException {
+ Document document = createDocument();
+ Element rootNode = elem(document, "OwnershipControls", document);
+ rootNode.setAttribute("xmlns", S3Constants.S3_REST_API_XML_NAMESPACE);
+ Element ruleNode = elem(rootNode, "Rule", document);
+ elemWithText(ruleNode, "ObjectOwnership", objectOwnership, document);
+ return asString(document);
+ }
+}
diff --git
a/apis/s3/src/main/java/org/jclouds/s3/binders/BindPublicAccessBlockConfigurationToXMLPayload.java
b/apis/s3/src/main/java/org/jclouds/s3/binders/BindPublicAccessBlockConfigurationToXMLPayload.java
new file mode 100644
index 0000000000..3ca917936a
--- /dev/null
+++
b/apis/s3/src/main/java/org/jclouds/s3/binders/BindPublicAccessBlockConfigurationToXMLPayload.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.s3.binders;
+
+import static org.jclouds.s3.binders.XMLHelper.asString;
+import static org.jclouds.s3.binders.XMLHelper.createDocument;
+import static org.jclouds.s3.binders.XMLHelper.elem;
+import static org.jclouds.s3.binders.XMLHelper.elemWithText;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.core.MediaType;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.Binder;
+import org.jclouds.s3.domain.PublicAccessBlockConfiguration;
+import org.jclouds.s3.reference.S3Constants;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.google.common.base.Throwables;
+
+@Singleton
+public final class BindPublicAccessBlockConfigurationToXMLPayload implements
Binder {
+ @Override
+ public <R extends HttpRequest> R bindToRequest(R request, Object payload) {
+ PublicAccessBlockConfiguration configuration =
(PublicAccessBlockConfiguration) payload;
+ try {
+ request.setPayload(generatePayload(configuration));
+
request.getPayload().getContentMetadata().setContentType(MediaType.TEXT_XML);
+ return request;
+ } catch (Exception e) {
+ Throwables.propagateIfPossible(e);
+ throw new RuntimeException("error transforming configuration: " +
configuration, e);
+ }
+ }
+
+ protected String generatePayload(PublicAccessBlockConfiguration
configuration)
+ throws ParserConfigurationException, FactoryConfigurationError,
TransformerException {
+ Document document = createDocument();
+ Element rootNode = elem(document, "PublicAccessBlockConfiguration",
document);
+ rootNode.setAttribute("xmlns", S3Constants.S3_REST_API_XML_NAMESPACE);
+ elemWithText(rootNode, "BlockPublicAcls",
String.valueOf(configuration.blockPublicAcls()), document);
+ elemWithText(rootNode, "IgnorePublicAcls",
String.valueOf(configuration.ignorePublicAcls()), document);
+ elemWithText(rootNode, "BlockPublicPolicy",
String.valueOf(configuration.blockPublicPolicy()), document);
+ elemWithText(rootNode, "RestrictPublicBuckets",
String.valueOf(configuration.restrictPublicBuckets()), document);
+ return asString(document);
+ }
+}
diff --git
a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3BlobIntegrationLiveTest.java
b/apis/s3/src/main/java/org/jclouds/s3/domain/PublicAccessBlockConfiguration.java
similarity index 54%
copy from
providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3BlobIntegrationLiveTest.java
copy to
apis/s3/src/main/java/org/jclouds/s3/domain/PublicAccessBlockConfiguration.java
index ddbe114358..e7ae00296d 100644
---
a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3BlobIntegrationLiveTest.java
+++
b/apis/s3/src/main/java/org/jclouds/s3/domain/PublicAccessBlockConfiguration.java
@@ -14,20 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jclouds.aws.s3.blobstore.integration;
+package org.jclouds.s3.domain;
-import org.jclouds.s3.blobstore.integration.S3BlobIntegrationLiveTest;
-import org.testng.annotations.Test;
-import org.testng.SkipException;
+import com.google.auto.value.AutoValue;
+import com.google.common.annotations.Beta;
-@Test(groups = "live", testName = "AWSS3BlobIntegrationLiveTest")
-public class AWSS3BlobIntegrationLiveTest extends S3BlobIntegrationLiveTest {
- public AWSS3BlobIntegrationLiveTest() {
- provider = "aws-s3";
- }
+@AutoValue
+@Beta
+public abstract class PublicAccessBlockConfiguration {
+ public abstract boolean blockPublicAcls();
+ public abstract boolean ignorePublicAcls();
+ public abstract boolean blockPublicPolicy();
+ public abstract boolean restrictPublicBuckets();
- @Override
- public void testCopyIfModifiedSinceNegative() throws Exception {
- throw new SkipException("S3 supports copyIfModifiedSince but test uses
time in the future which Amazon does not support");
+ public static PublicAccessBlockConfiguration create(boolean
blockPublicAcls, boolean ignorePublicAcls, boolean blockPublicPolicy, boolean
restrictPublicBuckets) {
+ return new AutoValue_PublicAccessBlockConfiguration(blockPublicAcls,
ignorePublicAcls, blockPublicPolicy, restrictPublicBuckets);
}
}
diff --git a/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java
b/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java
index 9c994b2fe3..11707d942c 100644
--- a/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java
+++ b/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java
@@ -163,11 +163,16 @@ public class S3ClientLiveTest extends
BaseBlobStoreIntegrationTest {
}
+ protected void allowPublicReadable(String containerName) {
+ }
+
@Test(groups = {"fails-on-s3proxy"})
public void testCopyCannedAccessPolicyPublic() throws Exception {
String containerName = getContainerName();
String destinationContainer = getContainerName();
try {
+ allowPublicReadable(destinationContainer);
+
addBlobToContainer(containerName, sourceKey);
validateContent(containerName, sourceKey);
@@ -193,6 +198,7 @@ public class S3ClientLiveTest extends
BaseBlobStoreIntegrationTest {
final String publicReadWriteObjectKey = "public-read-write-acl";
final String containerName = getContainerName();
try {
+ allowPublicReadable(containerName);
S3Object object = getApi().newS3Object();
object.getMetadata().setKey(publicReadWriteObjectKey);
object.setPayload("");
@@ -295,6 +301,7 @@ public class S3ClientLiveTest extends
BaseBlobStoreIntegrationTest {
final String publicReadObjectKey = "public-read-acl";
final String containerName = getContainerName();
try {
+ allowPublicReadable(containerName);
S3Object object = getApi().newS3Object();
object.getMetadata().setKey(publicReadObjectKey);
object.setPayload("");
@@ -715,6 +722,7 @@ public class S3ClientLiveTest extends
BaseBlobStoreIntegrationTest {
public void testUpdateBucketCannedACL() throws Exception {
String containerName = getContainerName();
try {
+ allowPublicReadable(containerName);
getApi().updateBucketCannedACL(containerName,
CannedAccessPolicy.PUBLIC_READ);
AccessControlList acl = getApi().getBucketACL(containerName);
assertThat(acl.hasPermission(GroupGranteeURI.ALL_USERS,
Permission.READ)).isTrue();
@@ -730,6 +738,7 @@ public class S3ClientLiveTest extends
BaseBlobStoreIntegrationTest {
public void testUpdateObjectCannedACL() throws Exception {
String containerName = getContainerName();
try {
+ allowPublicReadable(containerName);
String key = "testUpdateObjectCannedACL";
S3Object object = getApi().newS3Object();
object.getMetadata().setKey(key);
diff --git a/apis/s3/src/test/java/org/jclouds/s3/services/BucketsLiveTest.java
b/apis/s3/src/test/java/org/jclouds/s3/services/BucketsLiveTest.java
index 285f72b9b1..3e2b8bca17 100644
--- a/apis/s3/src/test/java/org/jclouds/s3/services/BucketsLiveTest.java
+++ b/apis/s3/src/test/java/org/jclouds/s3/services/BucketsLiveTest.java
@@ -25,14 +25,12 @@ import static
org.jclouds.s3.domain.AccessControlList.Permission.READ;
import static org.jclouds.s3.domain.AccessControlList.Permission.READ_ACP;
import static org.jclouds.s3.domain.AccessControlList.Permission.WRITE;
import static org.jclouds.s3.domain.AccessControlList.Permission.WRITE_ACP;
-import static org.jclouds.s3.domain.CannedAccessPolicy.PUBLIC_READ;
import static org.jclouds.s3.domain.Payer.BUCKET_OWNER;
import static org.jclouds.s3.domain.Payer.REQUESTER;
import static org.jclouds.s3.options.ListBucketOptions.Builder.afterMarker;
import static org.jclouds.s3.options.ListBucketOptions.Builder.delimiter;
import static org.jclouds.s3.options.ListBucketOptions.Builder.maxResults;
import static org.jclouds.s3.options.ListBucketOptions.Builder.withPrefix;
-import static org.jclouds.s3.options.PutBucketOptions.Builder.withBucketAcl;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
@@ -53,6 +51,7 @@ import
org.jclouds.s3.domain.AccessControlList.EmailAddressGrantee;
import org.jclouds.s3.domain.AccessControlList.Grant;
import org.jclouds.s3.domain.BucketLogging;
import org.jclouds.s3.domain.BucketMetadata;
+import org.jclouds.s3.domain.CannedAccessPolicy;
import org.jclouds.s3.domain.ListBucketResponse;
import org.jclouds.s3.domain.S3Object;
import org.jclouds.util.Strings2;
@@ -154,7 +153,9 @@ public class BucketsLiveTest extends
BaseBlobStoreIntegrationTest {
public void testPublicReadAccessPolicy() throws Exception {
String bucketName = getScratchContainerName();
try {
- getApi().putBucketInRegion(null, bucketName,
withBucketAcl(PUBLIC_READ));
+ getApi().putBucketInRegion(/*region=*/ null, bucketName);
+ allowPublicReadable(bucketName);
+ getApi().updateBucketCannedACL(bucketName,
CannedAccessPolicy.PUBLIC_READ);
AccessControlList acl = getApi().getBucketACL(bucketName);
assertTrue(acl.hasPermission(ALL_USERS, READ), acl.toString());
// TODO: I believe that the following should work based on the above
acl assertion passing.
@@ -209,11 +210,15 @@ public class BucketsLiveTest extends
BaseBlobStoreIntegrationTest {
}
}
+ protected void allowPublicReadable(String containerName) {
+ }
+
@Test(groups = {"fails-on-s3proxy"})
public void testBucketLogging() throws Exception {
final String bucketName = getContainerName();
final String targetBucket = getContainerName();
try {
+ allowPublicReadable(targetBucket);
assertNull(getApi().getBucketLogging(bucketName));
setupAclForBucketLoggingTarget(targetBucket);
diff --git
a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java
b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java
index ec458c0962..42ce2a8164 100644
---
a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java
+++
b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java
@@ -729,12 +729,16 @@ public class BaseBlobIntegrationTest extends
BaseBlobStoreIntegrationTest {
testPut(payload, null, new ByteSourcePayload(byteSource), length, new
PutOptions().multipart(true));
}
+ protected void allowPublicReadable(String containerName) {
+ }
+
@Test(groups = { "integration", "live" })
public void testSetBlobAccess() throws Exception {
BlobStore blobStore = view.getBlobStore();
String containerName = getContainerName();
String blobName = "set-access-blob-name";
try {
+ allowPublicReadable(containerName);
addBlobToContainer(containerName, blobName, blobName,
MediaType.TEXT_PLAIN);
assertThat(blobStore.getBlobAccess(containerName,
blobName)).isEqualTo(BlobAccess.PRIVATE);
@@ -778,6 +782,7 @@ public class BaseBlobIntegrationTest extends
BaseBlobStoreIntegrationTest {
public void testPutBlobAccessMultipart() throws Exception {
BlobStore blobStore = view.getBlobStore();
String containerName = getContainerName();
+ allowPublicReadable(containerName);
ByteSource byteSource = TestUtils.randomByteSource().slice(0,
getMinimumMultipartBlobSize());
Payload payload = Payloads.newByteSourcePayload(byteSource);
payload.getContentMetadata().setContentLength(byteSource.size());
diff --git
a/providers/aws-s3/src/main/java/org/jclouds/aws/s3/blobstore/AWSS3BlobStore.java
b/providers/aws-s3/src/main/java/org/jclouds/aws/s3/blobstore/AWSS3BlobStore.java
index b795cec5b0..042d41d789 100644
---
a/providers/aws-s3/src/main/java/org/jclouds/aws/s3/blobstore/AWSS3BlobStore.java
+++
b/providers/aws-s3/src/main/java/org/jclouds/aws/s3/blobstore/AWSS3BlobStore.java
@@ -29,6 +29,7 @@ import
org.jclouds.aws.s3.blobstore.options.AWSS3PutObjectOptions;
import org.jclouds.aws.s3.blobstore.options.AWSS3PutOptions;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.domain.Blob;
+import org.jclouds.blobstore.domain.ContainerAccess;
import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
@@ -47,7 +48,9 @@ import
org.jclouds.s3.blobstore.functions.ContainerToBucketListOptions;
import org.jclouds.s3.blobstore.functions.ObjectToBlob;
import org.jclouds.s3.blobstore.functions.ObjectToBlobMetadata;
import org.jclouds.s3.domain.BucketMetadata;
+import org.jclouds.s3.domain.CannedAccessPolicy;
import org.jclouds.s3.domain.ObjectMetadata;
+import org.jclouds.s3.domain.PublicAccessBlockConfiguration;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
@@ -58,6 +61,7 @@ import com.google.common.base.Supplier;
public class AWSS3BlobStore extends S3BlobStore {
private final BlobToObject blob2Object;
+ private final AWSS3Client awsSync;
@Inject
AWSS3BlobStore(BlobStoreContext context, BlobUtils blobUtils,
Supplier<Location> defaultLocation,
@@ -70,6 +74,7 @@ public class AWSS3BlobStore extends S3BlobStore {
super(context, blobUtils, defaultLocation, locations, slicer, sync,
convertBucketsToStorageMetadata,
container2BucketListOptions, bucket2ResourceList, object2Blob,
blob2ObjectGetOptions, blob2Object,
blob2ObjectMetadata, object2BlobMd, fetchBlobMetadataProvider);
+ this.awsSync = sync;
this.blob2Object = blob2Object;
}
@@ -102,6 +107,30 @@ public class AWSS3BlobStore extends S3BlobStore {
// JCLOUDS-334 for details.
return false;
}
+ // AWS blocks creating buckets with public-read canned ACL by default
since 25 April 2023. Instead create a bucket, override the block, and set the
ACL.
+ if (options.isPublicRead()) {
+ boolean created = super.createContainerInLocation(location,
container, new CreateContainerOptions());
+ if (!created) {
+ return false;
+ }
+ awsSync.putBucketOwnershipControls(container, "ObjectWriter");
+ awsSync.putPublicAccessBlock(container,
PublicAccessBlockConfiguration.create(
+ /*blockPublicAcls=*/ false, /*ignorePublicAcls=*/ false,
/*blockPublicPolicy=*/ false, /*restrictPublicBuckets=*/ false));
+ awsSync.updateBucketCannedACL(container,
CannedAccessPolicy.PUBLIC_READ);
+ return true;
+ }
return super.createContainerInLocation(location, container, options);
}
+
+ @Override
+ public void setContainerAccess(String container, ContainerAccess access) {
+ CannedAccessPolicy acl = CannedAccessPolicy.PRIVATE;
+ if (access == ContainerAccess.PUBLIC_READ) {
+ acl = CannedAccessPolicy.PUBLIC_READ;
+ awsSync.putBucketOwnershipControls(container, "ObjectWriter");
+ awsSync.putPublicAccessBlock(container,
PublicAccessBlockConfiguration.create(
+ /*blockPublicAcls=*/ false, /*ignorePublicAcls=*/ false,
/*blockPublicPolicy=*/ false, /*restrictPublicBuckets=*/ false));
+ }
+ awsSync.updateBucketCannedACL(container, acl);
+ }
}
diff --git
a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ClientLiveTest.java
b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ClientLiveTest.java
index 1d04891d20..7cbcfddd49 100644
--- a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ClientLiveTest.java
+++ b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ClientLiveTest.java
@@ -37,6 +37,7 @@ import org.jclouds.s3.S3ClientLiveTest;
import org.jclouds.s3.domain.ListBucketResponse;
import org.jclouds.s3.domain.ObjectMetadata;
import org.jclouds.s3.domain.ObjectMetadata.StorageClass;
+import org.jclouds.s3.domain.PublicAccessBlockConfiguration;
import org.jclouds.s3.domain.S3Object;
import org.testng.ITestContext;
import org.testng.annotations.BeforeClass;
@@ -56,6 +57,13 @@ public class AWSS3ClientLiveTest extends S3ClientLiveTest {
return view.unwrapApi(AWSS3Client.class);
}
+ @Override
+ protected void allowPublicReadable(String containerName) {
+ getApi().putBucketOwnershipControls(containerName, "ObjectWriter");
+ getApi().putPublicAccessBlock(containerName,
PublicAccessBlockConfiguration.create(
+ /*blockPublicAcls=*/ false, /*ignorePublicAcls=*/ false,
/*blockPublicPolicy=*/ false, /*restrictPublicBuckets=*/ false));
+ }
+
@BeforeClass(groups = { "integration", "live" })
@Override
public void setUpResourcesOnThisThread(ITestContext testContext) throws
Exception {
diff --git
a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3BlobIntegrationLiveTest.java
b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3BlobIntegrationLiveTest.java
index ddbe114358..f42a28ff5e 100644
---
a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3BlobIntegrationLiveTest.java
+++
b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3BlobIntegrationLiveTest.java
@@ -16,7 +16,9 @@
*/
package org.jclouds.aws.s3.blobstore.integration;
+import org.jclouds.s3.S3Client;
import org.jclouds.s3.blobstore.integration.S3BlobIntegrationLiveTest;
+import org.jclouds.s3.domain.PublicAccessBlockConfiguration;
import org.testng.annotations.Test;
import org.testng.SkipException;
@@ -26,6 +28,14 @@ public class AWSS3BlobIntegrationLiveTest extends
S3BlobIntegrationLiveTest {
provider = "aws-s3";
}
+ @Override
+ protected void allowPublicReadable(String containerName) {
+ S3Client client = view.unwrapApi(S3Client.class);
+ client.putBucketOwnershipControls(containerName, "ObjectWriter");
+ client.putPublicAccessBlock(containerName,
PublicAccessBlockConfiguration.create(
+ /*blockPublicAcls=*/ false, /*ignorePublicAcls=*/ false,
/*blockPublicPolicy=*/ false, /*restrictPublicBuckets=*/ false));
+ }
+
@Override
public void testCopyIfModifiedSinceNegative() throws Exception {
throw new SkipException("S3 supports copyIfModifiedSince but test uses
time in the future which Amazon does not support");
diff --git
a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/services/AWSBucketsLiveTest.java
b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/services/AWSBucketsLiveTest.java
index ca2e5cf8a5..fafff79fbc 100644
---
a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/services/AWSBucketsLiveTest.java
+++
b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/services/AWSBucketsLiveTest.java
@@ -16,7 +16,6 @@
*/
package org.jclouds.aws.s3.services;
-import static org.jclouds.s3.options.PutBucketOptions.Builder.withBucketAcl;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
@@ -25,6 +24,7 @@ import org.jclouds.s3.domain.AccessControlList;
import org.jclouds.s3.domain.AccessControlList.GroupGranteeURI;
import org.jclouds.s3.domain.AccessControlList.Permission;
import org.jclouds.s3.domain.CannedAccessPolicy;
+import org.jclouds.s3.domain.PublicAccessBlockConfiguration;
import org.jclouds.s3.services.BucketsLiveTest;
import org.testng.annotations.Test;
@@ -36,6 +36,13 @@ public class AWSBucketsLiveTest extends BucketsLiveTest {
provider = "aws-s3";
}
+ @Override
+ protected void allowPublicReadable(String containerName) {
+ getApi().putBucketOwnershipControls(containerName, "ObjectWriter");
+ getApi().putPublicAccessBlock(containerName,
PublicAccessBlockConfiguration.create(
+ /*blockPublicAcls=*/ false, /*ignorePublicAcls=*/ false,
/*blockPublicPolicy=*/ false, /*restrictPublicBuckets=*/ false));
+ }
+
public void testDefaultBucketLocation() throws Exception {
String bucketName = getContainerName();
@@ -53,7 +60,9 @@ public class AWSBucketsLiveTest extends BucketsLiveTest {
public void testEu() throws Exception {
final String bucketName = getScratchContainerName();
try {
- getApi().putBucketInRegion(Region.EU_WEST_1, bucketName + "eu",
withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
+ getApi().putBucketInRegion(Region.EU_WEST_1, bucketName);
+ allowPublicReadable(bucketName);
+ getApi().updateBucketCannedACL(bucketName,
CannedAccessPolicy.PUBLIC_READ);
assertConsistencyAware(new Runnable() {
public void run() {
try {