There is currently an srv_queue converter which is capable of taking the
output of a dynamic name and determining the queue length for a given
server. In addition there is a sample fetcher for whether a server is
currently up. This simply combines the two such that srv_is_up can be
used as a converter too.
To avoid code duplication, extract the server lookup into a function
from the existing converter and re-use in both implementations.
Future work might extend this to other sample fetchers for servers, but
this is probably the most useful for acl routing.
---
doc/configuration.txt | 8 ++++++++
src/backend.c | 35 +++++++++++++++++++++++++++++------
2 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 946ce8ace..ca71348df 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -20144,6 +20144,7 @@ secure_memcmp(var)
string boolean
set-var(var[,cond...]) any same
sha1 binary binary
sha2([bits]) binary binary
+srv_is_up string boolean
srv_queue string integer
strcmp(var) string boolean
sub(value) integer integer
@@ -21405,6 +21406,13 @@ sha2([<bits>])
Please note that this converter is only available when HAProxy has been
compiled with USE_OPENSSL.
+srv_is_up
+ Takes an input value of type string, either a server name or
<backend>/<server>
+ format and returns true when the designated server is currently UP.
Can be used
+ in places where we want to look up a server status from a dynamic
name, like a
+ cookie value (e.g. req.cook(SRVID),srv_is_up) and then make a decision to
+ direct a request elsewhere.
+
srv_queue
Takes an input value of type string, either a server name or
<backend>/<server>
format and returns the number of queued streams on that server. Can be used
diff --git a/src/backend.c b/src/backend.c
index bee6277a5..135b2c4a0 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -3738,11 +3738,9 @@ static int sample_conv_nbsrv(const struct arg
*args, struct sample *smp, void *p
return 1;
}
-static int
-sample_conv_srv_queue(const struct arg *args, struct sample *smp,
void *private)
+static struct server *sample_conv_srv(struct sample *smp)
{
struct proxy *px;
- struct server *srv;
char *bksep;
if (!smp_make_safe(smp))
@@ -3754,15 +3752,39 @@ sample_conv_srv_queue(const struct arg *args,
struct sample *smp, void *private)
*bksep = '\0';
px = proxy_find_by_name(smp->data.u.str.area, PR_CAP_BE, 0);
if (!px)
- return 0;
+ return NULL;
smp->data.u.str.area = bksep + 1;
} else {
if (!(smp->px->cap & PR_CAP_BE))
- return 0;
+ return NULL;
px = smp->px;
}
- srv = server_find(px, smp->data.u.str.area);
+ return server_find(px, smp->data.u.str.area);
+}
+
+static int
+sample_conv_srv_is_up(const struct arg *args, struct sample *smp,
void *private)
+{
+ struct server *srv = sample_conv_srv(smp);
+
+ if (!srv)
+ return 0;
+
+ smp->data.type = SMP_T_BOOL;
+ if (!(srv->cur_admin & SRV_ADMF_MAINT) &&
+ (!(srv->check.state & CHK_ST_CONFIGURED) || (srv->cur_state !=
SRV_ST_STOPPED)))
+ smp->data.u.sint = 1;
+ else
+ smp->data.u.sint = 0;
+ return 1;
+}
+
+static int
+sample_conv_srv_queue(const struct arg *args, struct sample *smp,
void *private)
+{
+ struct server *srv = sample_conv_srv(smp);
+
if (!srv)
return 0;
@@ -3804,6 +3826,7 @@ INITCALL1(STG_REGISTER, sample_register_fetches,
&smp_kws);
/* Note: must not be declared <const> as its list will be overwritten */
static struct sample_conv_kw_list sample_conv_kws = {ILH, {
{ "nbsrv", sample_conv_nbsrv, 0, NULL, SMP_T_STR, SMP_T_SINT },
+ { "srv_is_up", sample_conv_srv_is_up, 0, NULL, SMP_T_STR, SMP_T_BOOL },
{ "srv_queue", sample_conv_srv_queue, 0, NULL, SMP_T_STR, SMP_T_SINT },
{ /* END */ },
}};
--
2.49.0