3

I am attempting to use a backend under the following condition:

It is the prod site being requested (i.e. there is mysite.com and beta.mysite.com)

AND

It's an api request

OR

It's an opt-in request

I have the following acls setup for each condition:

acl prod hdr_beg(host) -i mysite.com
acl url_api  path_beg /api/
acl url_opt-in  path_beg /opt-in/

I would now like to redirect to the prod-api-backend like so:

use_backend prod-api-backend if prod AND ( url_api OR url_opt-in )

However, I can't seem to figure out how I can write a condition like this without receiving a configuration error.

ThaDon
  • 497
  • 1
  • 5
  • 15

2 Answers2

4

There's no 'and' in haproxy logic, but if you expand the brackets and write it like this, you should be good:

use_backend prod-api-backend if prod url_opt-in or prod url_api
Sirch
  • 5,785
  • 4
  • 20
  • 36
  • 1
    I thought `AND` and `&&` were allowed, it's just that they're implicit? Thanks for the tip, expanding out the brackets makes perfect sense – ThaDon Apr 20 '18 at 13:40
  • Implicit - check out "parse_acl_cond" method in https://github.com/haproxy/haproxy/blob/v1.6.0/src/acl.c – Sirch Apr 20 '18 at 14:20
1

Conjunction ("and") operators are implicit when you specify multiple conditions. Meaning when you do:

acl foo ...
acl bar ...
use_backend ... if foo bar

The use_backend is performed if both foo and bar match. You can specify || or or in between foo and bar to make it a disjunction.

If you want a mixture of conjunction and disjunction, it's easiest to take a different approach.

If you specify multiple conditions under the same ACL identifier, the ACL evaluates as true if any of the conditions match. For example:

acl url_matches  path_beg /api/
acl url_matches  path_beg /opt-in/
use_backend ... if url_matches

Since you're using the same condition (the url_matches part), you can also specify multiple comparison targets on a single line. For example:

acl url_matches path_beg /api/ /opt-in/
use_backend ... if url_matches

So putting it together, picking the latter of the above 2 solutions, you can do:

acl prod hdr_beg(host) -i mysite.com
acl url_matches path_beg /api/ /opt-in/
use_backend prod-api-backend if prod url_matches
phemmer
  • 5,909
  • 2
  • 27
  • 36