From: Amaury Denoyelle Date: Mon, 6 Jul 2026 13:51:41 +0000 (+0200) Subject: MINOR: proxy: implement unpublished backend keyword X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6e2fb9ba936db946c2c679ff11f4b6e1e305d792;p=thirdparty%2Fhaproxy.git MINOR: proxy: implement unpublished backend keyword Add a new "unpublished" proxy keyword. This allows to start a backend instance in unpublished state. This can be reverted via "publish backend" on the CLI. This keyword is restricted to backend and listen sections. This patch is a simple feature implementation, however it can be considered as a must-have when using dynamic backends. As such, it should be backported up to 3.4. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 111e8e52f..bcdd50c25 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -6041,6 +6041,7 @@ Note: Some dangerous and not recommended directives are intentionnaly not acl X (!) X X X backlog X X X - balance X - X X +be-unpublished - - X X bind - X X - capture cookie - X X - capture request header - X X - @@ -6642,6 +6643,26 @@ balance url_param [check_post] See also : "cookie", "hash-type". +be-unpublished + Instructs the backend to start in the unpublished state. + + May be used in the following contexts: tcp, http, log + + May be used in sections : defaults | frontend | listen | backend + no | no | yes | yes + + In effect, any use_backend and default_backend rules from another proxy which + reference the current proxy are ignored and the next content switching rules + are evaluated. This can be bypassed though via a "force-be-switch" rule. + + This state is similar to the disabled one but with some differences. First, + an unpublished backend will still be fully initialized, including the server + health checks which remain active. Finally, a backend can be publicly exposed + via the command "publish backend" on the CLI. See the management manual. + + See also : "force-be-switch" + + bind [
]: [, ...] [param*] bind / [, ...] [param*] Define one or several listening addresses and/or ports in a frontend. @@ -7879,7 +7900,7 @@ force-be-switch { if | unless } May be used in sections: defaults | frontend | listen | backend no | yes | yes | no - See also : "disabled" + See also : "be-unpublished", "disabled" filter [param*] diff --git a/reg-tests/stream/test_content_switching.vtc b/reg-tests/stream/test_content_switching.vtc index ef518690a..a071ace88 100644 --- a/reg-tests/stream/test_content_switching.vtc +++ b/reg-tests/stream/test_content_switching.vtc @@ -58,6 +58,10 @@ haproxy h1 -conf { backend be2 http-request return status 200 hdr "x-be" %[be_name] + backend be_unpublished + be-unpublished + http-request return status 200 hdr "x-be" %[be_name] + backend be_disabled disabled http-request return status 200 hdr "x-be" %[be_name] @@ -93,6 +97,12 @@ client c2 -connect ${h1_fe2S_sock} { expect resp.status == 200 expect resp.http.x-be == "be_default" + # Static rule on unpublished backend -> continue to next rule + txreq -hdr "x-target: be_unpublished" + rxresp + expect resp.status == 200 + expect resp.http.x-be == "be" + # Static rule on disabled backend -> continue to next rule txreq -hdr "x-target: be_disabled" rxresp diff --git a/src/proxy.c b/src/proxy.c index 2de25245f..5d81c0918 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -1228,6 +1228,29 @@ static int proxy_parse_tcpka_intvl(char **args, int section, struct proxy *proxy } #endif +/* Parser for "be-unpublished" proxy keyword. */ +static int proxy_parse_be_unpublished(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + if (curpx->cap & PR_CAP_DEF) { + memprintf(err, "'%s' not allowed in 'defaults' section.", args[0]); + goto err; + } + + if (!(curpx->cap & PR_CAP_BE)) { + memprintf(err, "'%s' only available in backend or listen section.", args[0]); + goto err; + } + + curpx->flags |= PR_FL_BE_UNPUBLISHED; + + return 0; + + err: + return -1; +} + static int proxy_parse_force_be_switch(char **args, int section_type, struct proxy *curpx, const struct proxy *defpx, const char *file, int line, char **err) @@ -4344,6 +4367,7 @@ static struct cfg_kw_list cfg_kws = {ILH, { { CFG_LISTEN, "clitcpka-intvl", proxy_parse_tcpka_intvl }, { CFG_LISTEN, "srvtcpka-intvl", proxy_parse_tcpka_intvl }, #endif + { CFG_LISTEN, "be-unpublished", proxy_parse_be_unpublished }, { CFG_LISTEN, "force-be-switch", proxy_parse_force_be_switch }, { CFG_LISTEN, "guid", proxy_parse_guid }, { 0, NULL, NULL },