mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 22:31:28 +02:00
MEDIUM: checks: Support expression to set the port
Since we have a session attached to tcp-check healthchecks, It is possible use sample expression and variables. In addition, it is possible to add tcp-check set-var rules to define custom variables. So, now, a sample expression can be used to define the port to use to establish a connection for a tcp-check connect rule. For instance: tcp-check set-var(check.port) int(8888) tcp-check connect port var(check.port)
This commit is contained in:
parent
5c28874a69
commit
b7d30098f3
@ -9821,10 +9821,10 @@ tcp-check connect [params*]
|
|||||||
default Use default options of the server line to do the health
|
default Use default options of the server line to do the health
|
||||||
checks. This parameter is exclusive with all other options.
|
checks. This parameter is exclusive with all other options.
|
||||||
|
|
||||||
port if not set, check port or server port is used.
|
port <expr> if not set, check port or server port is used.
|
||||||
It tells HAProxy where to open the connection to.
|
It tells HAProxy where to open the connection to.
|
||||||
<port> must be a valid TCP port source integer, from 1 to
|
<port> must be a valid TCP port source integer, from 1 to
|
||||||
65535.
|
65535 or an sample-fetch expression.
|
||||||
|
|
||||||
addr <ip> defines the IP address to do the health check.
|
addr <ip> defines the IP address to do the health check.
|
||||||
|
|
||||||
|
@ -225,6 +225,7 @@ struct tcpcheck_connect {
|
|||||||
int alpn_len; /* ALPN string length */
|
int alpn_len; /* ALPN string length */
|
||||||
uint16_t options; /* options when setting up a new connection */
|
uint16_t options; /* options when setting up a new connection */
|
||||||
uint16_t port; /* port to connect to */
|
uint16_t port; /* port to connect to */
|
||||||
|
struct sample_expr *port_expr; /* sample expr to determine the port, may be NULL */
|
||||||
struct sockaddr_storage addr; /* the address to the connect */
|
struct sockaddr_storage addr; /* the address to the connect */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
53
src/checks.c
53
src/checks.c
@ -64,6 +64,7 @@
|
|||||||
#include <proto/dns.h>
|
#include <proto/dns.h>
|
||||||
#include <proto/proto_udp.h>
|
#include <proto/proto_udp.h>
|
||||||
#include <proto/ssl_sock.h>
|
#include <proto/ssl_sock.h>
|
||||||
|
#include <proto/sample.h>
|
||||||
|
|
||||||
static int httpchk_expect(struct server *s, int done);
|
static int httpchk_expect(struct server *s, int done);
|
||||||
static int tcpcheck_get_step_id(struct check *, struct tcpcheck_rule *);
|
static int tcpcheck_get_step_id(struct check *, struct tcpcheck_rule *);
|
||||||
@ -2870,6 +2871,15 @@ static enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct
|
|||||||
port = 0;
|
port = 0;
|
||||||
if (!port && connect->port)
|
if (!port && connect->port)
|
||||||
port = connect->port;
|
port = connect->port;
|
||||||
|
if (!port && connect->port_expr) {
|
||||||
|
struct sample *smp;
|
||||||
|
|
||||||
|
smp = sample_fetch_as_type(check->proxy, check->sess, NULL,
|
||||||
|
SMP_OPT_DIR_REQ | SMP_OPT_FINAL,
|
||||||
|
connect->port_expr, SMP_T_SINT);
|
||||||
|
if (smp)
|
||||||
|
port = smp->data.u.sint;
|
||||||
|
}
|
||||||
if (!port && is_inet_addr(&connect->addr))
|
if (!port && is_inet_addr(&connect->addr))
|
||||||
port = get_host_port(&connect->addr);
|
port = get_host_port(&connect->addr);
|
||||||
if (!port && check->port)
|
if (!port && check->port)
|
||||||
@ -3465,6 +3475,7 @@ static void free_tcpcheck(struct tcpcheck_rule *rule, int in_pool)
|
|||||||
case TCPCHK_ACT_CONNECT:
|
case TCPCHK_ACT_CONNECT:
|
||||||
free(rule->connect.sni);
|
free(rule->connect.sni);
|
||||||
free(rule->connect.alpn);
|
free(rule->connect.alpn);
|
||||||
|
release_sample_expr(rule->connect.port_expr);
|
||||||
break;
|
break;
|
||||||
case TCPCHK_ACT_COMMENT:
|
case TCPCHK_ACT_COMMENT:
|
||||||
break;
|
break;
|
||||||
@ -4084,11 +4095,12 @@ static struct tcpcheck_rule *parse_tcpcheck_action(char **args, int cur_arg, str
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct tcpcheck_rule *parse_tcpcheck_connect(char **args, int cur_arg, struct proxy *px, struct list *rules,
|
static struct tcpcheck_rule *parse_tcpcheck_connect(char **args, int cur_arg, struct proxy *px, struct list *rules,
|
||||||
char **errmsg)
|
const char *file, int line, char **errmsg)
|
||||||
{
|
{
|
||||||
struct tcpcheck_rule *chk = NULL;
|
struct tcpcheck_rule *chk = NULL;
|
||||||
struct sockaddr_storage *sk = NULL;
|
struct sockaddr_storage *sk = NULL;
|
||||||
char *comment = NULL, *sni = NULL, *alpn = NULL;
|
char *comment = NULL, *sni = NULL, *alpn = NULL;
|
||||||
|
struct sample_expr *port_expr = NULL;
|
||||||
unsigned short conn_opts = 0;
|
unsigned short conn_opts = 0;
|
||||||
long port = 0;
|
long port = 0;
|
||||||
int alpn_len = 0;
|
int alpn_len = 0;
|
||||||
@ -4144,14 +4156,41 @@ static struct tcpcheck_rule *parse_tcpcheck_connect(char **args, int cur_arg, st
|
|||||||
cur_arg++;
|
cur_arg++;
|
||||||
}
|
}
|
||||||
else if (strcmp(args[cur_arg], "port") == 0) {
|
else if (strcmp(args[cur_arg], "port") == 0) {
|
||||||
|
const char *p, *end;
|
||||||
|
|
||||||
if (!*(args[cur_arg+1])) {
|
if (!*(args[cur_arg+1])) {
|
||||||
memprintf(errmsg, "'%s' expects a port number as argument.", args[cur_arg]);
|
memprintf(errmsg, "'%s' expects a port number or a sample expression as argument.", args[cur_arg]);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
cur_arg++;
|
cur_arg++;
|
||||||
port = atol(args[cur_arg]);
|
|
||||||
if (port > 65535 || port < 1) {
|
port = 0;
|
||||||
memprintf(errmsg, "expects a valid TCP port (from range 1 to 65535), got %s.", args[cur_arg]);
|
release_sample_expr(port_expr);
|
||||||
|
p = args[cur_arg]; end = p + strlen(p);
|
||||||
|
port = read_uint(&p, end);
|
||||||
|
if (p != end) {
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
px->conf.args.ctx = ARGC_SRV;
|
||||||
|
port_expr = sample_parse_expr((char *[]){args[cur_arg], NULL}, &idx,
|
||||||
|
file, line, errmsg, &px->conf.args, NULL);
|
||||||
|
|
||||||
|
if (!port_expr) {
|
||||||
|
memprintf(errmsg, "error detected while parsing port expression : %s", *errmsg);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (!(port_expr->fetch->val & SMP_VAL_BE_CHK_RUL)) {
|
||||||
|
memprintf(errmsg, "error detected while parsing port expression : "
|
||||||
|
" fetch method '%s' extracts information from '%s', "
|
||||||
|
"none of which is available here.\n",
|
||||||
|
args[cur_arg], sample_src_names(port_expr->fetch->use));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
px->http_needed |= !!(port_expr->fetch->use & SMP_USE_HTTP_ANY);
|
||||||
|
}
|
||||||
|
else if (port > 65535 || port < 1) {
|
||||||
|
memprintf(errmsg, "expects a valid TCP port (from range 1 to 65535) or a sample expression, got %s.",
|
||||||
|
args[cur_arg]);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4231,6 +4270,7 @@ static struct tcpcheck_rule *parse_tcpcheck_connect(char **args, int cur_arg, st
|
|||||||
chk->connect.sni = sni;
|
chk->connect.sni = sni;
|
||||||
chk->connect.alpn = alpn;
|
chk->connect.alpn = alpn;
|
||||||
chk->connect.alpn_len= alpn_len;
|
chk->connect.alpn_len= alpn_len;
|
||||||
|
chk->connect.port_expr= port_expr;
|
||||||
if (sk)
|
if (sk)
|
||||||
chk->connect.addr = *sk;
|
chk->connect.addr = *sk;
|
||||||
return chk;
|
return chk;
|
||||||
@ -4239,6 +4279,7 @@ static struct tcpcheck_rule *parse_tcpcheck_connect(char **args, int cur_arg, st
|
|||||||
free(alpn);
|
free(alpn);
|
||||||
free(sni);
|
free(sni);
|
||||||
free(comment);
|
free(comment);
|
||||||
|
release_sample_expr(port_expr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4535,7 +4576,7 @@ static int proxy_parse_tcpcheck(char **args, int section, struct proxy *curpx,
|
|||||||
|
|
||||||
cur_arg = 1;
|
cur_arg = 1;
|
||||||
if (strcmp(args[cur_arg], "connect") == 0)
|
if (strcmp(args[cur_arg], "connect") == 0)
|
||||||
chk = parse_tcpcheck_connect(args, cur_arg, curpx, rules, errmsg);
|
chk = parse_tcpcheck_connect(args, cur_arg, curpx, rules, file, line, errmsg);
|
||||||
else if (strcmp(args[cur_arg], "send") == 0 || strcmp(args[cur_arg], "send-binary") == 0)
|
else if (strcmp(args[cur_arg], "send") == 0 || strcmp(args[cur_arg], "send-binary") == 0)
|
||||||
chk = parse_tcpcheck_send(args, cur_arg, rules, errmsg);
|
chk = parse_tcpcheck_send(args, cur_arg, rules, errmsg);
|
||||||
else if (strcmp(args[cur_arg], "expect") == 0)
|
else if (strcmp(args[cur_arg], "expect") == 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user