MEDIUM: cfgparse: allow a proxy to designate the defaults section to use
Now it becomes possible to specify "from foo" on a frontend/listen/backend or even on a "defaults" line, to mention that defaults section "foo" needs to be used to preset the proxy's settings. When not set, the last section remains used. In case the designated name is found at multiple places, it is rejected and an error indicates two occurrences of the same name. Similarly, if the section name is found, its name must only use valid characters. This allows multiple named defaults section to continue to coexist without the risk that they will cause trouble by accident. When it comes to "defaults" relying on another defaults, what happens is just that a new defaults section is created from the designated one. This will make it possible for example to reuse some settings such as log-format like below: defaults tcp-clear log stdout local0 info log-format "%ci:%cp/%b/%si:%sp %ST %ts %U/%B %{+Q}r" defaults tcp-ssl log stdout local0 info log-format "%ci:%cp/%b/%si:%sp %ST %ts %U/%B %{+Q}r ssl=%sslv" defaults http-clear from tcp-clear mode http defaults http-ssl from tcp-ssl mode http frontend fe1 from http-clear bind :8001 frontend fe2 from http-ssl bind :8002 A small corner case remains in the error detection, if a second defaults section appears with the same name after the point where it was used, and nobody references it, the duplicate will not be detected. This could be addressed by performing the syntactic checks in check_config_validity(), and by postponing the freeing of the defaults, after tagging a defaults section as explicitly looked up by another section. This doesn't seem that important at the moment though.
This commit is contained in:
parent
e90904d5a9
commit
7c0b4d861e
|
@ -3119,15 +3119,10 @@ timeout client <timeout>
|
|||
----------
|
||||
|
||||
Proxy configuration can be located in a set of sections :
|
||||
- defaults [<name>]
|
||||
- frontend <name>
|
||||
- backend <name>
|
||||
- listen <name>
|
||||
|
||||
A "defaults" section sets default parameters for all other sections following
|
||||
its declaration. Those default parameters are reset by the next "defaults"
|
||||
section. See below for the list of parameters which can be set in a "defaults"
|
||||
section. The name is optional but its use is encouraged for better readability.
|
||||
- defaults [<name>] [ from <defaults_name> ]
|
||||
- frontend <name> [ from <defaults_name> ]
|
||||
- backend <name> [ from <defaults_name> ]
|
||||
- listen <name> [ from <defaults_name> ]
|
||||
|
||||
A "frontend" section describes a set of listening sockets accepting client
|
||||
connections.
|
||||
|
@ -3138,6 +3133,29 @@ to forward incoming connections.
|
|||
A "listen" section defines a complete proxy with its frontend and backend
|
||||
parts combined in one section. It is generally useful for TCP-only traffic.
|
||||
|
||||
A "defaults" section resets all settings to the documented ones and presets new
|
||||
ones for use by subsequent sections. All of "frontend", "backend" and "listen"
|
||||
sections always take their initial settings from a defaults section, by default
|
||||
the latest one that appears before the newly created section. It is possible to
|
||||
explicitly designate a specific "defaults" section to load the initial settings
|
||||
from by indicating its name on the section line after the optional keyword
|
||||
"from". While "defaults" section do not impose a name, this use is encouraged
|
||||
for better readability. It is also the only way to designate a specific section
|
||||
to use instead of the default previous one. Since "defaults" section names are
|
||||
optional, by default a very permissive check is applied on their name and these
|
||||
are even permitted to overlap. However if a "defaults" section is referenced by
|
||||
any other section, its name must comply with the syntax imposed on all proxy
|
||||
names, and this name must be unique among the defaults sections. Please note
|
||||
that regardless of what is currently permitted, it is recommended to avoid
|
||||
duplicate section names in general and to respect the same syntax as for proxy
|
||||
names. This rule might be enforced in a future version.
|
||||
|
||||
Note that it is even possible for a defaults section to take its initial
|
||||
settings from another one, and as such, inherit settings across multiple levels
|
||||
of defaults sections. This can be convenient to establish certain configuration
|
||||
profiles to carry groups of default settings (e.g. TCP vs HTTP or short vs long
|
||||
timeouts) but can quickly become confusing to follow.
|
||||
|
||||
All proxy names must be formed from upper and lower case letters, digits,
|
||||
'-' (dash), '_' (underscore) , '.' (dot) and ':' (colon). ACL names are
|
||||
case-sensitive, which means that "www" and "WWW" are two different proxies.
|
||||
|
|
|
@ -237,7 +237,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
|
||||
if ((*args[2] && (!*args[3] || strcmp(args[2], "from") != 0)) ||
|
||||
alertif_too_many_args(3, file, linenum, args, &err_code)) {
|
||||
if (rc & PR_CAP_FE)
|
||||
ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum);
|
||||
goto out;
|
||||
|
@ -245,7 +246,46 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||
}
|
||||
|
||||
if (rc & PR_CAP_LISTEN) { /* new proxy or defaults section */
|
||||
curproxy = alloc_new_proxy(args[1], rc, file, linenum, curr_defproxy, &errmsg);
|
||||
const char *name = args[1];
|
||||
int arg = 2;
|
||||
|
||||
if (rc & PR_CAP_DEF && strcmp(args[1], "from") == 0 && *args[2] && !*args[3]) {
|
||||
// also support "defaults from blah" (no name then)
|
||||
arg = 1;
|
||||
name = "";
|
||||
}
|
||||
|
||||
/* only regular proxies inherit from the previous defaults section */
|
||||
if (!(rc & PR_CAP_DEF))
|
||||
curr_defproxy = last_defproxy;
|
||||
|
||||
if (strcmp(args[arg], "from") == 0) {
|
||||
curr_defproxy = proxy_find_by_name(args[arg+1], PR_CAP_DEF, 0);
|
||||
|
||||
if (!curr_defproxy) {
|
||||
ha_alert("parsing [%s:%d] : defaults section '%s' not found for %s '%s'.\n", file, linenum, args[arg+1], proxy_cap_str(rc), name);
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ebpt_next_dup(&curr_defproxy->conf.by_name)) {
|
||||
struct proxy *px2 = container_of(ebpt_next_dup(&curr_defproxy->conf.by_name), struct proxy, conf.by_name);
|
||||
|
||||
ha_alert("parsing [%s:%d] : ambiguous defaults section name '%s' referenced by %s '%s' exists at least at %s:%d and %s:%d.\n",
|
||||
file, linenum, args[arg+1], proxy_cap_str(rc), name,
|
||||
curr_defproxy->conf.file, curr_defproxy->conf.line, px2->conf.file, px2->conf.line);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
err = invalid_char(args[arg+1]);
|
||||
if (err) {
|
||||
ha_alert("parsing [%s:%d] : character '%c' is not permitted in defaults section name '%s' when designated by its name (section found at %s:%d).\n",
|
||||
file, linenum, *err, args[arg+1], curr_defproxy->conf.file, curr_defproxy->conf.line);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
}
|
||||
|
||||
curproxy = alloc_new_proxy(name, rc, file, linenum, curr_defproxy, &errmsg);
|
||||
if (!curproxy) {
|
||||
ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
|
|
Loading…
Reference in New Issue