Hello list, tl;dr is: How can I avoid configuring dozens of http-request with
the same acl?
My use case is a haproxy cluster receiving requests for hundreds of distinct
hostnames, several of them with a dozen or so distinct paths, and a few more
than 5k distinct backends that sends these requests to a cluster of about 15k
containers. In the very beginning we were adding one http-request per rule but
this wasn't scaling well, so changed the approach to a map() converter with
something like `<hostname>#<path> <backend-name>` which improved performance a
lot.
Now we're starting to add other dimensions to that host+path matching, which is
at least query params and header matching, so starting again with one
http-request keyword per rule, which we already know that will not scale.
My starting idea was to evolve the map() converter strategy to add these new
matching rules but couldn't figure out a way to do it. I thought about making
two levels of map() but it doesn't allow dynamic input, so I wouldn't have a
way to configure the second one.
Another idea was to mimic how other proxies do their configuration: an outer
block defines the hostname level, everything inside that block already have an
implicit `{ hdr(host) host1 }`. A second block within the first one defines the
path, so everything inside it has already an implicit `{ path /bar }`.
Maybe haproxy has already a keyword or configuration for that use case, if so
I'd love to hear some advices. If not this is a draft of a proposal that I'd
love to hear from you if it's something doable:
case (acl-name|anonymous-acl) {
http-request bar # outer acl implicit
http-request baz if { hdr(x-bar) baz } # outer acl implicitly ANDed here
case (acl-name|anonymous-acl) {
http-request bazz # both outer acls ANDing here
}
}
case keyword starts a block, a closing brace alone in the line closes the inner
block. Indentation doesn't matter at all. haproxy now knows that if the outer
acl doesn't match, all the inner keywords should be ignored. Does it make sense?
~jm