Skip to content

HDDS-16115. Reject invalid lifecycle rule Status values - #10980

Draft
F64116045 wants to merge 2 commits into
apache:masterfrom
F64116045:HDDS-16115
Draft

HDDS-16115. Reject invalid lifecycle rule Status values#10980
F64116045 wants to merge 2 commits into
apache:masterfrom
F64116045:HDDS-16115

Conversation

@F64116045

@F64116045 F64116045 commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

According to the Amazon S3 LifecycleRule API, lifecycle rule Status is required and only accepts the exact values Enabled or Disabled. This behavior is covered by test_lifecycle_invalid_status in ceph/s3-tests.

S3 Gateway previously checked only whether Status was missing or empty. It then converted the value using "Enabled".equals(status), causing every other non-empty value, including enabled, disabled, and invalid, to be accepted and interpreted as a disabled rule.

This pull request validates Status against the two values defined by Amazon S3 before converting the lifecycle rule. Parameterized tests cover invalid values, while the valid path explicitly verifies both Enabled and Disabled.

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-16115

How was this patch tested?

mvn -pl hadoop-ozone/s3gateway -DskipDocs=true -DskipShade \
  -Dtest=TestS3LifecycleConfigurationPut test
mvn -pl hadoop-ozone/s3gateway -DskipDocs=true -DskipShade test

Ceph S3 compatibility test against a locally built packaged Ozone cluster:

S3TEST_CONF=<path-to-s3tests.conf> python -m pytest -v \
  s3tests/functional/test_s3.py::test_lifecycle_invalid_status

String status = rule.getStatus();
if (status == null || status.isEmpty()) {
throw S3ErrorTable.newError(S3ErrorTable.MALFORMED_XML,
"The Status element is required in LifecycleConfiguration");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The second String argument here is actually resource, and OS3Exception serializes it as <Resource>. So this text does not replace <Message>; MALFORMED_XML already provides that. I think the one-argument overload is enough here.

This is in the existing missing-Status path, so I plan to follow it up separately with response coverage. If it makes more sense to include it here, I can update the patch.

@chungen0126
chungen0126 self-requested a review August 10, 2026 06:14

@ashishkumar50 ashishkumar50 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@F64116045 Thanks for the patch, mostly looks fine to me. Here are few minor suggestions.

throw S3ErrorTable.newError(S3ErrorTable.MALFORMED_XML,
"The Status element is required in LifecycleConfiguration");
}
if (!"Enabled".equals(status) && !"Disabled".equals(status)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Instead of hardcoding, good to define constant and use everywhere for Enabled/Disabled.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated to use STATUS_ENABLED and STATUS_DISABLED in the validation and builder mapping. Thanks.

@Test
public void testPutValidLifecycleConfiguration() throws Exception {
assertEquals(HTTP_OK, bucketEndpoint.put("bucket1", onePrefix()).getStatus());
assertEquals(HTTP_OK, bucketEndpoint.put("bucket1", withStatus("Disabled")).getStatus());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Verify valid input for both Enabled and Disabled.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added the Enabled test, thanks.

private OmLCRule convertToOmRule(Rule rule) throws OMException, OS3Exception {
if (rule.getStatus() == null || rule.getStatus().isEmpty()) {
String status = rule.getStatus();
if (status == null || status.isEmpty()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You can use StringUtils.isEmpty(status)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated to use StringUtils.isEmpty(status). Thanks.

@Gargi-jais11 Gargi-jais11 added the s3 S3 Gateway label Aug 10, 2026
@F64116045

F64116045 commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @ashishkumar50 for the review. I’ve addressed the suggestions.
(BTW I’ll mark the PR ready for review once the CI run on my fork passes.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

s3 S3 Gateway

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants