mirror of
https://github.com/minio/minio.git
synced 2025-02-28 13:59:15 -05:00
allow lifecycle rules with overlapping prefixes (#10053)
This commit is contained in:
parent
7b14e9b660
commit
48aebf2d9d
@ -24,9 +24,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errLifecycleTooManyRules = Errorf("Lifecycle configuration allows a maximum of 1000 rules")
|
errLifecycleTooManyRules = Errorf("Lifecycle configuration allows a maximum of 1000 rules")
|
||||||
errLifecycleNoRule = Errorf("Lifecycle configuration should have at least one rule")
|
errLifecycleNoRule = Errorf("Lifecycle configuration should have at least one rule")
|
||||||
errLifecycleOverlappingPrefix = Errorf("Lifecycle configuration has rules with overlapping prefix")
|
errLifecycleDuplicateID = Errorf("Lifecycle configuration has rule with the same ID. Rule ID must be unique.")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Action represents a delete action or other transition
|
// Action represents a delete action or other transition
|
||||||
@ -115,17 +115,15 @@ func (lc Lifecycle) Validate() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Compare every rule's prefix with every other rule's prefix
|
// Make sure Rule ID is unique
|
||||||
for i := range lc.Rules {
|
for i := range lc.Rules {
|
||||||
if i == len(lc.Rules)-1 {
|
if i == len(lc.Rules)-1 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// N B Empty prefixes overlap with all prefixes
|
|
||||||
otherRules := lc.Rules[i+1:]
|
otherRules := lc.Rules[i+1:]
|
||||||
for _, otherRule := range otherRules {
|
for _, otherRule := range otherRules {
|
||||||
if strings.HasPrefix(lc.Rules[i].Prefix(), otherRule.Prefix()) ||
|
if lc.Rules[i].ID == otherRule.ID {
|
||||||
strings.HasPrefix(otherRule.Prefix(), lc.Rules[i].Prefix()) {
|
return errLifecycleDuplicateID
|
||||||
return errLifecycleOverlappingPrefix
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,12 @@ import (
|
|||||||
func TestParseAndValidateLifecycleConfig(t *testing.T) {
|
func TestParseAndValidateLifecycleConfig(t *testing.T) {
|
||||||
// Test for lifecycle config with more than 1000 rules
|
// Test for lifecycle config with more than 1000 rules
|
||||||
var manyRules []Rule
|
var manyRules []Rule
|
||||||
rule := Rule{
|
|
||||||
Status: "Enabled",
|
|
||||||
Expiration: Expiration{Days: ExpirationDays(3)},
|
|
||||||
}
|
|
||||||
for i := 0; i < 1001; i++ {
|
for i := 0; i < 1001; i++ {
|
||||||
|
rule := Rule{
|
||||||
|
ID: fmt.Sprintf("toManyRule%d", i),
|
||||||
|
Status: "Enabled",
|
||||||
|
Expiration: Expiration{Days: ExpirationDays(i)},
|
||||||
|
}
|
||||||
manyRules = append(manyRules, rule)
|
manyRules = append(manyRules, rule)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +43,7 @@ func TestParseAndValidateLifecycleConfig(t *testing.T) {
|
|||||||
|
|
||||||
// Test for lifecycle config with rules containing overlapping prefixes
|
// Test for lifecycle config with rules containing overlapping prefixes
|
||||||
rule1 := Rule{
|
rule1 := Rule{
|
||||||
|
ID: "rule1",
|
||||||
Status: "Enabled",
|
Status: "Enabled",
|
||||||
Expiration: Expiration{Days: ExpirationDays(3)},
|
Expiration: Expiration{Days: ExpirationDays(3)},
|
||||||
Filter: Filter{
|
Filter: Filter{
|
||||||
@ -49,6 +51,7 @@ func TestParseAndValidateLifecycleConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
rule2 := Rule{
|
rule2 := Rule{
|
||||||
|
ID: "rule2",
|
||||||
Status: "Enabled",
|
Status: "Enabled",
|
||||||
Expiration: Expiration{Days: ExpirationDays(3)},
|
Expiration: Expiration{Days: ExpirationDays(3)},
|
||||||
Filter: Filter{
|
Filter: Filter{
|
||||||
@ -63,6 +66,31 @@ func TestParseAndValidateLifecycleConfig(t *testing.T) {
|
|||||||
t.Fatal("Failed to marshal lifecycle config with rules having overlapping prefix")
|
t.Fatal("Failed to marshal lifecycle config with rules having overlapping prefix")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test for lifecycle rules with duplicate IDs
|
||||||
|
rule3 := Rule{
|
||||||
|
ID: "duplicateID",
|
||||||
|
Status: "Enabled",
|
||||||
|
Expiration: Expiration{Days: ExpirationDays(3)},
|
||||||
|
Filter: Filter{
|
||||||
|
Prefix: "/a/b",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
rule4 := Rule{
|
||||||
|
ID: "duplicateID",
|
||||||
|
Status: "Enabled",
|
||||||
|
Expiration: Expiration{Days: ExpirationDays(4)},
|
||||||
|
Filter: Filter{
|
||||||
|
And: And{
|
||||||
|
Prefix: "/x/z",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
duplicateIDRules := []Rule{rule3, rule4}
|
||||||
|
duplicateIDLcConfig, err := xml.Marshal(Lifecycle{Rules: duplicateIDRules})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Failed to marshal lifecycle config of rules with duplicate ID.")
|
||||||
|
}
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
inputConfig string
|
inputConfig string
|
||||||
expectedParsingErr error
|
expectedParsingErr error
|
||||||
@ -70,7 +98,8 @@ func TestParseAndValidateLifecycleConfig(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{ // Valid lifecycle config
|
{ // Valid lifecycle config
|
||||||
inputConfig: `<LifecycleConfiguration>
|
inputConfig: `<LifecycleConfiguration>
|
||||||
<Rule>
|
<Rule>
|
||||||
|
<ID>testRule1</ID>
|
||||||
<Filter>
|
<Filter>
|
||||||
<Prefix>prefix</Prefix>
|
<Prefix>prefix</Prefix>
|
||||||
</Filter>
|
</Filter>
|
||||||
@ -78,6 +107,7 @@ func TestParseAndValidateLifecycleConfig(t *testing.T) {
|
|||||||
<Expiration><Days>3</Days></Expiration>
|
<Expiration><Days>3</Days></Expiration>
|
||||||
</Rule>
|
</Rule>
|
||||||
<Rule>
|
<Rule>
|
||||||
|
<ID>testRule2</ID>
|
||||||
<Filter>
|
<Filter>
|
||||||
<Prefix>another-prefix</Prefix>
|
<Prefix>another-prefix</Prefix>
|
||||||
</Filter>
|
</Filter>
|
||||||
@ -114,7 +144,12 @@ func TestParseAndValidateLifecycleConfig(t *testing.T) {
|
|||||||
{ // lifecycle config with rules having overlapping prefix
|
{ // lifecycle config with rules having overlapping prefix
|
||||||
inputConfig: string(overlappingLcConfig),
|
inputConfig: string(overlappingLcConfig),
|
||||||
expectedParsingErr: nil,
|
expectedParsingErr: nil,
|
||||||
expectedValidationErr: errLifecycleOverlappingPrefix,
|
expectedValidationErr: nil,
|
||||||
|
},
|
||||||
|
{ // lifecycle config with rules having overlapping prefix
|
||||||
|
inputConfig: string(duplicateIDLcConfig),
|
||||||
|
expectedParsingErr: nil,
|
||||||
|
expectedValidationErr: errLifecycleDuplicateID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user