mirror of https://github.com/minio/minio.git
ilm: fix x-amz-expiration header evaluation (#16029)
This commit is contained in:
parent
7b7356f04c
commit
7ba281728f
|
@ -358,7 +358,7 @@ func (lc Lifecycle) Eval(obj ObjectOpts, now time.Time) Event {
|
||||||
// Specifying the Days tag will automatically perform ExpiredObjectDeleteMarker cleanup
|
// Specifying the Days tag will automatically perform ExpiredObjectDeleteMarker cleanup
|
||||||
// once delete markers are old enough to satisfy the age criteria.
|
// once delete markers are old enough to satisfy the age criteria.
|
||||||
// https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-configuration-examples.html
|
// https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-configuration-examples.html
|
||||||
if expectedExpiry := ExpectedExpiryTime(obj.ModTime, int(rule.Expiration.Days)); now.After(expectedExpiry) {
|
if expectedExpiry := ExpectedExpiryTime(obj.ModTime, int(rule.Expiration.Days)); now.IsZero() || now.After(expectedExpiry) {
|
||||||
events = append(events, Event{
|
events = append(events, Event{
|
||||||
Action: DeleteVersionAction,
|
Action: DeleteVersionAction,
|
||||||
RuleID: rule.ID,
|
RuleID: rule.ID,
|
||||||
|
@ -380,7 +380,7 @@ func (lc Lifecycle) Eval(obj ObjectOpts, now time.Time) Event {
|
||||||
if !obj.IsLatest && !rule.NoncurrentVersionExpiration.IsDaysNull() {
|
if !obj.IsLatest && !rule.NoncurrentVersionExpiration.IsDaysNull() {
|
||||||
// Non current versions should be deleted if their age exceeds non current days configuration
|
// Non current versions should be deleted if their age exceeds non current days configuration
|
||||||
// https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html#intro-lifecycle-rules-actions
|
// https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html#intro-lifecycle-rules-actions
|
||||||
if expectedExpiry := ExpectedExpiryTime(obj.SuccessorModTime, int(rule.NoncurrentVersionExpiration.NoncurrentDays)); now.After(expectedExpiry) {
|
if expectedExpiry := ExpectedExpiryTime(obj.SuccessorModTime, int(rule.NoncurrentVersionExpiration.NoncurrentDays)); now.IsZero() || now.After(expectedExpiry) {
|
||||||
events = append(events, Event{
|
events = append(events, Event{
|
||||||
Action: DeleteVersionAction,
|
Action: DeleteVersionAction,
|
||||||
RuleID: rule.ID,
|
RuleID: rule.ID,
|
||||||
|
@ -393,7 +393,7 @@ func (lc Lifecycle) Eval(obj ObjectOpts, now time.Time) Event {
|
||||||
if !obj.DeleteMarker && obj.TransitionStatus != TransitionComplete {
|
if !obj.DeleteMarker && obj.TransitionStatus != TransitionComplete {
|
||||||
// Non current versions should be transitioned if their age exceeds non current days configuration
|
// Non current versions should be transitioned if their age exceeds non current days configuration
|
||||||
// https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html#intro-lifecycle-rules-actions
|
// https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html#intro-lifecycle-rules-actions
|
||||||
if due, ok := rule.NoncurrentVersionTransition.NextDue(obj); ok && now.After(due) {
|
if due, ok := rule.NoncurrentVersionTransition.NextDue(obj); ok && (now.IsZero() || now.After(due)) {
|
||||||
events = append(events, Event{
|
events = append(events, Event{
|
||||||
Action: TransitionVersionAction,
|
Action: TransitionVersionAction,
|
||||||
RuleID: rule.ID,
|
RuleID: rule.ID,
|
||||||
|
@ -408,7 +408,7 @@ func (lc Lifecycle) Eval(obj ObjectOpts, now time.Time) Event {
|
||||||
if obj.IsLatest && !obj.DeleteMarker {
|
if obj.IsLatest && !obj.DeleteMarker {
|
||||||
switch {
|
switch {
|
||||||
case !rule.Expiration.IsDateNull():
|
case !rule.Expiration.IsDateNull():
|
||||||
if time.Now().UTC().After(rule.Expiration.Date.Time) {
|
if now.IsZero() || now.After(rule.Expiration.Date.Time) {
|
||||||
events = append(events, Event{
|
events = append(events, Event{
|
||||||
Action: DeleteAction,
|
Action: DeleteAction,
|
||||||
RuleID: rule.ID,
|
RuleID: rule.ID,
|
||||||
|
@ -416,7 +416,7 @@ func (lc Lifecycle) Eval(obj ObjectOpts, now time.Time) Event {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
case !rule.Expiration.IsDaysNull():
|
case !rule.Expiration.IsDaysNull():
|
||||||
if expectedExpiry := ExpectedExpiryTime(obj.ModTime, int(rule.Expiration.Days)); now.After(expectedExpiry) {
|
if expectedExpiry := ExpectedExpiryTime(obj.ModTime, int(rule.Expiration.Days)); now.IsZero() || now.After(expectedExpiry) {
|
||||||
events = append(events, Event{
|
events = append(events, Event{
|
||||||
Action: DeleteAction,
|
Action: DeleteAction,
|
||||||
RuleID: rule.ID,
|
RuleID: rule.ID,
|
||||||
|
@ -426,7 +426,7 @@ func (lc Lifecycle) Eval(obj ObjectOpts, now time.Time) Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
if obj.TransitionStatus != TransitionComplete {
|
if obj.TransitionStatus != TransitionComplete {
|
||||||
if due, ok := rule.Transition.NextDue(obj); ok && now.After(due) {
|
if due, ok := rule.Transition.NextDue(obj); ok && (now.IsZero() || now.After(due)) {
|
||||||
events = append(events, Event{
|
events = append(events, Event{
|
||||||
Action: TransitionAction,
|
Action: TransitionAction,
|
||||||
RuleID: rule.ID,
|
RuleID: rule.ID,
|
||||||
|
|
|
@ -932,3 +932,69 @@ func TestParseLifecycleConfigWithID(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFilterAndSetPredictionHeaders(t *testing.T) {
|
||||||
|
lc := Lifecycle{
|
||||||
|
Rules: []Rule{
|
||||||
|
{
|
||||||
|
ID: "rule-1",
|
||||||
|
Status: "Enabled",
|
||||||
|
Filter: Filter{
|
||||||
|
set: true,
|
||||||
|
Prefix: Prefix{
|
||||||
|
string: "folder1/folder1/exp_dt=2022-",
|
||||||
|
set: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Expiration: Expiration{
|
||||||
|
Days: 1,
|
||||||
|
set: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
opts ObjectOpts
|
||||||
|
lc Lifecycle
|
||||||
|
want int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
opts: ObjectOpts{
|
||||||
|
Name: "folder1/folder1/exp_dt=2022-08-01/obj-1",
|
||||||
|
ModTime: time.Now().UTC().Add(-10 * 24 * time.Hour),
|
||||||
|
VersionID: "",
|
||||||
|
IsLatest: true,
|
||||||
|
NumVersions: 1,
|
||||||
|
},
|
||||||
|
want: 1,
|
||||||
|
lc: lc,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
opts: ObjectOpts{
|
||||||
|
Name: "folder1/folder1/exp_dt=9999-01-01/obj-1",
|
||||||
|
ModTime: time.Now().UTC().Add(-10 * 24 * time.Hour),
|
||||||
|
VersionID: "",
|
||||||
|
IsLatest: true,
|
||||||
|
NumVersions: 1,
|
||||||
|
},
|
||||||
|
want: 0,
|
||||||
|
lc: lc,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i, tc := range tests {
|
||||||
|
t.Run(fmt.Sprintf("test-%d", i+1), func(t *testing.T) {
|
||||||
|
if got := tc.lc.FilterRules(tc.opts); len(got) != tc.want {
|
||||||
|
t.Fatalf("Expected %d rules to match but got %d", tc.want, len(got))
|
||||||
|
}
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
tc.lc.SetPredictionHeaders(w, tc.opts)
|
||||||
|
expHdr, ok := w.Header()[xhttp.AmzExpiration]
|
||||||
|
switch {
|
||||||
|
case ok && tc.want == 0:
|
||||||
|
t.Fatalf("Expected no rule to match but found x-amz-expiration header set: %v", expHdr)
|
||||||
|
case !ok && tc.want > 0:
|
||||||
|
t.Fatal("Expected x-amz-expiration header to be set but not found")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue