Skip to content

Commit

Permalink
BUG/MEDIUM: support multiple ignore-persist statements in backends
Browse files Browse the repository at this point in the history
  • Loading branch information
George Vine committed May 10, 2024
1 parent 7c78378 commit c5dcfd8
Show file tree
Hide file tree
Showing 10 changed files with 509 additions and 31 deletions.
32 changes: 27 additions & 5 deletions configuration/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -649,11 +649,16 @@ func TestGetBackend(t *testing.T) {
t.Errorf("MaxKeepAliveQueue not 101: %v", *b.MaxKeepAliveQueue)
}

if *b.IgnorePersist.Cond != "if" {
t.Errorf("IgnorePersist Cond not if: %v", *b.IgnorePersist.Cond)
}
if *b.IgnorePersist.CondTest != "acl-name" {
t.Errorf("IgnorePersist CondTest not acl-name: %v", *b.IgnorePersist.CondTest)
if len(b.IgnorePersistList) != 2 {
t.Errorf("IgnorePersistList has %d items, expected 2", len(b.IgnorePersistList))
} else if *b.IgnorePersistList[0].Cond != "if" {
t.Errorf("IgnorePersistList[0].Cond is %s, expected 'if'", *b.IgnorePersistList[0].Cond)
} else if *b.IgnorePersistList[0].CondTest != "acl-name" {
t.Errorf("IgnorePersistList[0].CondTest is %s, expected 'acl-name'", *b.IgnorePersistList[0].CondTest)
} else if *b.IgnorePersistList[1].Cond != "unless" {
t.Errorf("IgnorePersistList[1].Cond is %s, expected 'unless'", *b.IgnorePersistList[1].Cond)
} else if *b.IgnorePersistList[1].CondTest != "local_dst" {
t.Errorf("IgnorePersistList[1].CondTest is %s, expected 'local_dst'", *b.IgnorePersistList[1].CondTest)
}

if *b.ForcePersist.Cond != "unless" {
Expand Down Expand Up @@ -945,6 +950,10 @@ func TestCreateEditDeleteBackend(t *testing.T) {
Enabled: misc.StringP("enabled"),
Header: "X-Client-Dst",
},
IgnorePersistList: []*models.IgnorePersist{
{Cond: misc.StringP("if"), CondTest: misc.StringP("host_www")},
{Cond: misc.StringP("unless"), CondTest: misc.StringP("missing_cl")},
},
},
{
Name: "created",
Expand Down Expand Up @@ -1262,6 +1271,19 @@ func compareBackends(x, y *models.Backend, t *testing.T) bool { //nolint:gocogni
x.HTTPConnectionMode = ""
}

if len(x.IgnorePersistList) != len(y.IgnorePersistList) {
return false
}
for i := range x.IgnorePersistList {
if *x.IgnorePersistList[i].Cond != *y.IgnorePersistList[i].Cond {
return false
}
if *x.IgnorePersistList[i].CondTest != *y.IgnorePersistList[i].CondTest {
return false
}
}
x.IgnorePersistList, y.IgnorePersistList = nil, nil

return reflect.DeepEqual(x, y)
}

Expand Down
60 changes: 40 additions & 20 deletions configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,8 @@ func (s *SectionParser) checkSpecialFields(fieldName string) (match bool, data i
return true, s.httpSendNameHeader()
case "ForcePersist":
return true, s.forcePersist()
case "IgnorePersist":
return true, s.ignorePersist()
case "IgnorePersistList":
return true, s.ignorePersistList()
case "Source":
return true, s.source()
case "Originalto":
Expand Down Expand Up @@ -1380,19 +1380,27 @@ func (s *SectionParser) forcePersist() interface{} {
return nil
}

func (s *SectionParser) ignorePersist() interface{} {
if s.Section == parser.Backends {
data, err := s.get("ignore-persist", false)
if err != nil {
return nil
}
d := data.(*types.IgnorePersist)
return &models.BackendIgnorePersist{
Cond: &d.Cond,
CondTest: &d.CondTest,
func (s *SectionParser) ignorePersistList() interface{} {
if s.Section != parser.Backends {
return nil
}
data, err := s.get("ignore-persist", false)
if err != nil {
return nil
}
d := data.([]types.IgnorePersist)
if len(d) == 0 {
return nil
}

items := make([]*models.IgnorePersist, len(d))
for i := range d {
items[i] = &models.IgnorePersist{
Cond: &d[i].Cond,
CondTest: &d[i].CondTest,
}
}
return nil
return items
}

func (s *SectionParser) source() interface{} {
Expand Down Expand Up @@ -1628,8 +1636,15 @@ func (s *SectionObject) checkSpecialFields(fieldName string, field reflect.Value
return true, s.httpSendNameHeader(field)
case "ForcePersist":
return true, s.forcePersist(field)
case "IgnorePersistList":
return true, s.ignorePersistList(field)
case "IgnorePersist":
return true, s.ignorePersist(field)
// "IgnorePersist" field (ignore_persist) is deprecated in favour of "IgnorePersistList" (ignore_persist_list).
// Backward compatibility during the sunset period is handled by callers of this library that perform payload
// transformation as necessary and remove the deprecated field.
// "IgnorePersist" is explicitly caught and ignored here as a safeguard against a runtime panic that can occur
// if callers behave unexpectedly. It should be removed at the end of the sunset period along with the field.
return true, nil
case "Source":
return true, s.source(field)
case "Originalto":
Expand Down Expand Up @@ -2894,18 +2909,23 @@ func (s *SectionObject) forcePersist(field reflect.Value) error {
})
}

func (s *SectionObject) ignorePersist(field reflect.Value) error {
func (s *SectionObject) ignorePersistList(field reflect.Value) error {
if valueIsNil(field) {
return s.set("ignore-persist", nil)
}
opt, ok := field.Elem().Interface().(models.BackendIgnorePersist)
data, ok := field.Interface().([]*models.IgnorePersist)
if !ok {
return misc.CreateTypeAssertError("ignore-persist")
}
return s.set("ignore-persist", types.IgnorePersist{
Cond: *opt.Cond,
CondTest: *opt.CondTest,
})

items := make([]types.IgnorePersist, len(data))
for i := range data {
items[i] = types.IgnorePersist{
Cond: *data[i].Cond,
CondTest: *data[i].CondTest,
}
}
return s.set("ignore-persist", items)
}

func (s *SectionObject) source(field reflect.Value) error {
Expand Down
1 change: 1 addition & 0 deletions configuration/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,7 @@ backend test
fullconn 11
max-keep-alive-queue 101
ignore-persist if acl-name
ignore-persist unless local_dst
force-persist unless acl-name-2
retry-on 504 505
http-send-name-header X-My-Awesome-Header
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/google/go-cmp v0.6.0
github.com/google/renameio v1.0.1
github.com/google/uuid v1.6.0
github.com/haproxytech/config-parser/v5 v5.1.3-0.20240430122521-77f35909a9c1
github.com/haproxytech/config-parser/v5 v5.1.4
github.com/json-iterator/go v1.1.12
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/mitchellh/mapstructure v1.5.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ github.com/google/renameio v1.0.1 h1:Lh/jXZmvZxb0BBeSY5VKEfidcbcbenKjZFzM/q0fSeU
github.com/google/renameio v1.0.1/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/haproxytech/config-parser/v5 v5.1.3-0.20240430122521-77f35909a9c1 h1:/+d5pcQlqH1IqBBb06WCyUQv6oorySLz2cNqzPQH9oM=
github.com/haproxytech/config-parser/v5 v5.1.3-0.20240430122521-77f35909a9c1/go.mod h1:16+1AbS+AvMZkDScIhergz2dqecQuEmjwV4Xt5ncS9s=
github.com/haproxytech/config-parser/v5 v5.1.4 h1:TArFSuRpYlmTanZjt3nVe7lNcPw+pXmth8tLW72ENeM=
github.com/haproxytech/config-parser/v5 v5.1.4/go.mod h1:16+1AbS+AvMZkDScIhergz2dqecQuEmjwV4Xt5ncS9s=
github.com/haproxytech/go-logger v1.1.0 h1:HgGtYaI1ApkvbQdsm7f9AzQQoxTB7w37criTflh7IQE=
github.com/haproxytech/go-logger v1.1.0/go.mod h1:OekUd8HCb7ubxMplzHUPBTHNxZmddOWfOjWclZsqIeM=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
Expand Down
167 changes: 166 additions & 1 deletion models/backend.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c5dcfd8

Please sign in to comment.