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


Reply via email to