Skip to content

Commit

Permalink
Introduce delete-exception in readonly mode
Browse files Browse the repository at this point in the history
  • Loading branch information
kuenishi committed Jul 10, 2024
1 parent e881875 commit 4994053
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 10 deletions.
8 changes: 8 additions & 0 deletions hadoop-hdds/common/src/main/resources/ozone-default.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1791,6 +1791,14 @@
Mostly used for system maintenance.</description>
</property>

<property>
<name>ozone.s3g.allow-delete</name>
<value>false</value>
<tag>OZONE, S3GATEWAY</tag>
<description>Whether the S3Gateway accepts DELETE as an exception in readonly mode.
Only effective in readonly mode.</description>
</property>

<property>
<name>ozone.om.save.metrics.interval</name>
<value>5m</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
import static org.apache.hadoop.ozone.s3.S3GatewayConfigKeys.OZONE_S3G_KERBEROS_KEYTAB_FILE_KEY;
import static org.apache.hadoop.ozone.s3.S3GatewayConfigKeys.OZONE_S3G_KERBEROS_PRINCIPAL_KEY;
import static org.apache.hadoop.ozone.s3.S3GatewayConfigKeys.OZONE_S3G_READONLY;
import static org.apache.hadoop.ozone.s3.S3GatewayConfigKeys.OZONE_S3G_ALLOW_DELETE;


/**
* This class is used to start/stop S3 compatible rest server.
Expand Down Expand Up @@ -95,6 +97,8 @@ public void start() throws IOException {
HddsServerUtil.initializeMetrics(ozoneConfiguration, "S3Gateway");
LOG.info("S3 Gateway Readonly mode: {}={}", OZONE_S3G_READONLY,
ozoneConfiguration.get(OZONE_S3G_READONLY));
LOG.info("S3 Gateway allow-delete: {}={}", OZONE_S3G_ALLOW_DELETE,
ozoneConfiguration.get(OZONE_S3G_ALLOW_DELETE));
httpServer.start();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ public final class S3GatewayConfigKeys {

public static final String OZONE_S3G_READONLY = "ozone.s3g.readonly";
public static final boolean OZONE_S3G_READONLY_DEFAULT = false;

public static final String OZONE_S3G_ALLOW_DELETE = "ozone.s3g.allow-delete";
public static final boolean OZONE_S3G_ALLOW_DELETE_DEFAULT = false;
/**
* Never constructed.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ public Response put(@PathParam("bucket") String bucketName,
S3GAction s3GAction = S3GAction.CREATE_BUCKET;

// Check if the S3Gateway status is readonly
Optional<Response> checkResult = checkIfReadonly();
Optional<Response> checkResult = checkIfReadonly(false);
if (checkResult.isPresent()) {
return checkResult.get();
}
Expand Down Expand Up @@ -356,7 +356,7 @@ public Response delete(@PathParam("bucket") String bucketName)
S3GAction s3GAction = S3GAction.DELETE_BUCKET;

// Check if the S3Gateway status is readonly
Optional<Response> checkResult = checkIfReadonly();
Optional<Response> checkResult = checkIfReadonly(true);
if (checkResult.isPresent()) {
return checkResult.get();
}
Expand Down Expand Up @@ -407,7 +407,7 @@ public MultiDeleteResponse multiDelete(@PathParam("bucket") String bucketName,
MultiDeleteResponse result = new MultiDeleteResponse();

// Check if the S3Gateway status is readonly
Optional<Response> checkResult = checkIfReadonly();
Optional<Response> checkResult = checkIfReadonly(false);
if (checkResult.isPresent()) {
Response res = checkResult.get();
result.addError(new Error("", res.getStatusInfo().getReasonPhrase(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hdds.conf.ConfigurationSource;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.ozone.OzoneConsts;
import org.apache.hadoop.ozone.audit.AuditAction;
import org.apache.hadoop.ozone.audit.AuditEventStatus;
Expand Down Expand Up @@ -383,14 +385,36 @@ protected boolean isAccessDenied(OMException ex) {
|| result == ResultCodes.INVALID_TOKEN;
}

protected Optional<Response> checkIfReadonly() {
/**
* Boolean logic combination behaviour
* | (READONLY, ALLOW_DELETE) | (F, _) | (T, F) | (T, T) |
* +--------------------------+--------+--------+--------+
* | PUT,POST | ok(a) | fail(d)| fail(g)|
* | GET,HEAD | ok(b) | ok(e) | ok(h) |
* | DELETE | ok(c) | fail(f)| ok(i) |
*
* Maybe we shall rename the method?
*
* @param isDeletion
* @return
*/
protected Optional<Response> checkIfReadonly(boolean isDeletion) {
// Check if the S3Gateway is in read-only mode or not.
if (getClient().getConfiguration().getBoolean(
ConfigurationSource conf = getClient().getConfiguration();
if (conf.getBoolean(
S3GatewayConfigKeys.OZONE_S3G_READONLY,
S3GatewayConfigKeys.OZONE_S3G_READONLY_DEFAULT)) {
if (isDeletion && conf.getBoolean(
S3GatewayConfigKeys.OZONE_S3G_ALLOW_DELETE,
S3GatewayConfigKeys.OZONE_S3G_ALLOW_DELETE_DEFAULT)) {
// case (i)
return Optional.empty();
}
// case (d, e, f, g, h)
return Optional.of(Response.status(HttpStatus.SC_METHOD_NOT_ALLOWED).
header("Allow", "GET,HEAD").build());
header("Allow", "GET,HEAD").build());
}
// case (a, b, c)
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public Response put(
InputStream body) throws IOException, OS3Exception {

// Check if the S3Gateway status is readonly
Optional<Response> checkResult = checkIfReadonly();
Optional<Response> checkResult = checkIfReadonly(false);
if (checkResult.isPresent()) {
return checkResult.get();
}
Expand Down Expand Up @@ -535,7 +535,7 @@ public Response delete(
IOException, OS3Exception {

// Check if the S3Gateway status is readonly
Optional<Response> checkResult = checkIfReadonly();
Optional<Response> checkResult = checkIfReadonly(true);
if (checkResult.isPresent()) {
return checkResult.get();
}
Expand Down Expand Up @@ -606,7 +606,7 @@ public Response initializeMultipartUpload(
throws IOException, OS3Exception {

// Check if the S3Gateway status is readonly
Optional<Response> checkResult = checkIfReadonly();
Optional<Response> checkResult = checkIfReadonly(false);
if (checkResult.isPresent()) {
return checkResult.get();
}
Expand Down Expand Up @@ -680,7 +680,7 @@ public Response completeMultipartUpload(@PathParam("bucket") String bucket,
throws IOException, OS3Exception {

// Check if the S3Gateway status is readonly
Optional<Response> checkResult = checkIfReadonly();
Optional<Response> checkResult = checkIfReadonly(false);
if (checkResult.isPresent()) {
return checkResult.get();
}
Expand Down

0 comments on commit 4994053

Please sign in to comment.