mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-10 09:07:02 +02:00
MINOR: checks: Add option to tcp-check expect rules to customize error status
It is now possible to specified the healthcheck status to use on error or on timeout for tcp-check expect rules. First, to define the error status, the option "error-status" must be used followed by "L4CON", "L6RSP", "L7RSP" or "L7STS". Then, to define the timeout status, the option "tout-status" must be used followed by "L4TOUT", "L6TOUT" or "L7TOUT". These options will be used to convert specific protocol healthchecks (redis, pgsql...) to tcp-check ones. x
This commit is contained in:
parent
1032059bd0
commit
cf80f2f263
@ -9871,7 +9871,8 @@ tcp-check connect [params*]
|
||||
See also : "option tcp-check", "tcp-check send", "tcp-check expect"
|
||||
|
||||
|
||||
tcp-check expect [min-recv <int>] [!] <match> <pattern>
|
||||
tcp-check expect [min-recv <int>] [error-status <st>] [tout-status <st>]
|
||||
[!] <match> <pattern>
|
||||
Specify data to be collected and analyzed during a generic health check
|
||||
May be used in sections: defaults | frontend | listen | backend
|
||||
no | no | yes | yes
|
||||
@ -9895,6 +9896,20 @@ tcp-check expect [min-recv <int>] [!] <match> <pattern>
|
||||
the match. Spaces are allowed between the exclamation mark and the
|
||||
keyword. See below for more details on the supported keywords.
|
||||
|
||||
error-status <st> is optional and can be used to set the check status if
|
||||
an error occurred during the expect rule evaluation.
|
||||
"L7RSP", "L7STS", "L6RSP" and "L4CON" are supported and
|
||||
may be used to set, respectively, HCHK_STATUS_L7RSP,
|
||||
HCHK_STATUS_L7STS, HCHK_STATUS_L6RSP or HCHK_STATUS_L4CON
|
||||
error status. By default "L7RSP" is used.
|
||||
|
||||
tout-status <st> is optional and can be used to set the check status if
|
||||
a timeout occurred during the expect rule evaluation.
|
||||
"L7TOUT", "L6TOUT", and "L4TOUT" are supported and may
|
||||
be used to set, respectively, HCHK_STATUS_L7TOUT,
|
||||
HCHK_STATUS_L6TOUT or HCHK_STATUS_L4TOUT timeout status.
|
||||
By default "L7TOUT" is used.
|
||||
|
||||
<pattern> is the pattern to look for. It may be a string or a regular
|
||||
expression. If the pattern contains spaces, they must be escaped
|
||||
with the usual backslash ('\').
|
||||
|
@ -264,6 +264,8 @@ struct tcpcheck_expect {
|
||||
int inverse; /* Match is inversed. */
|
||||
int with_capture; /* Match will store captured groups for back-reference in comment. */
|
||||
int min_recv; /* Minimum amount of data before an expect can be applied. (default: -1, ignored) */
|
||||
enum healthcheck_status err_status; /* The healthcheck status to use on error (default: L7RSP) */
|
||||
enum healthcheck_status tout_status; /* The healthcheck status to use on timeout (default: L7TOUT) */
|
||||
};
|
||||
|
||||
struct tcpcheck_action_kw {
|
||||
|
65
src/checks.c
65
src/checks.c
@ -737,11 +737,16 @@ static void chk_report_conn_err(struct check *check, int errno_bck, int expired)
|
||||
set_server_check_status(check, HCHK_STATUS_SOCKERR, err_msg);
|
||||
}
|
||||
else if (expired) {
|
||||
enum healthcheck_status tout = HCHK_STATUS_L7TOUT;
|
||||
|
||||
/* connection established but expired check */
|
||||
if (check->type == PR_O2_SSL3_CHK)
|
||||
set_server_check_status(check, HCHK_STATUS_L6TOUT, err_msg);
|
||||
else /* HTTP, SMTP, ... */
|
||||
set_server_check_status(check, HCHK_STATUS_L7TOUT, err_msg);
|
||||
else { /* HTTP, SMTP, ... */
|
||||
if (check->current_step && check->current_step->action == TCPCHK_ACT_EXPECT)
|
||||
tout = check->current_step->expect.tout_status;
|
||||
set_server_check_status(check, tout, err_msg);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
@ -3217,7 +3222,7 @@ static enum tcpcheck_eval_ret tcpcheck_eval_expect(struct check *check, struct t
|
||||
else
|
||||
chunk_appendf(&trash, " comment: '%s'", comment);
|
||||
}
|
||||
set_server_check_status(check, HCHK_STATUS_L7RSP, trash.area);
|
||||
set_server_check_status(check, expect->err_status, trash.area);
|
||||
ret = TCPCHK_EVAL_STOP;
|
||||
|
||||
out:
|
||||
@ -3380,7 +3385,7 @@ static int tcpcheck_main(struct check *check)
|
||||
comment = tcpcheck_get_step_comment(check, rule);
|
||||
if (comment)
|
||||
chunk_appendf(&trash, " comment: '%s'", comment);
|
||||
set_server_check_status(check, HCHK_STATUS_L7RSP, trash.area);
|
||||
set_server_check_status(check, rule->expect.err_status, trash.area);
|
||||
ret = -1;
|
||||
goto out_end_tcpcheck;
|
||||
}
|
||||
@ -3673,6 +3678,8 @@ static int add_tcpcheck_expect_str(struct tcpcheck_rules *rules, const char *str
|
||||
|
||||
expect = &tcpcheck->expect;
|
||||
expect->type = TCPCHK_EXPECT_STRING;
|
||||
expect->err_status = HCHK_STATUS_L7RSP;
|
||||
expect->tout_status = HCHK_STATUS_L7TOUT;
|
||||
expect->string = strdup(str);
|
||||
if (!expect->string) {
|
||||
pool_free(pool_head_tcpcheck_rule, tcpcheck);
|
||||
@ -4489,6 +4496,8 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str
|
||||
struct tcpcheck_rule *prev_check, *chk = NULL;
|
||||
char *str = NULL, *comment = NULL, *pattern = NULL;
|
||||
enum tcpcheck_expect_type type = TCPCHK_EXPECT_UNDEF;
|
||||
enum healthcheck_status err_st = HCHK_STATUS_L7RSP;
|
||||
enum healthcheck_status tout_st = HCHK_STATUS_L7TOUT;
|
||||
long min_recv = -1;
|
||||
int inverse = 0, with_capture = 0;
|
||||
|
||||
@ -4563,6 +4572,52 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (strcmp(args[cur_arg], "error-status") == 0) {
|
||||
if (in_pattern) {
|
||||
memprintf(errmsg, "[!] not supported with '%s'", args[cur_arg]);
|
||||
goto error;
|
||||
}
|
||||
if (!*(args[cur_arg+1])) {
|
||||
memprintf(errmsg, "'%s' expects a string as argument", args[cur_arg]);
|
||||
goto error;
|
||||
}
|
||||
if (strcasecmp(args[cur_arg+1], "L7RSP") == 0)
|
||||
err_st = HCHK_STATUS_L7RSP;
|
||||
else if (strcasecmp(args[cur_arg+1], "L7STS") == 0)
|
||||
err_st = HCHK_STATUS_L7STS;
|
||||
else if (strcasecmp(args[cur_arg+1], "L6RSP") == 0)
|
||||
err_st = HCHK_STATUS_L6RSP;
|
||||
else if (strcasecmp(args[cur_arg+1], "L4CON") == 0)
|
||||
err_st = HCHK_STATUS_L4CON;
|
||||
else {
|
||||
memprintf(errmsg, "'%s' only supports 'L4CON', 'L6RSP', 'L7RSP' or 'L7STS' status (got '%s').",
|
||||
args[cur_arg], args[cur_arg+1]);
|
||||
goto error;
|
||||
}
|
||||
cur_arg++;
|
||||
}
|
||||
else if (strcmp(args[cur_arg], "tout-status") == 0) {
|
||||
if (in_pattern) {
|
||||
memprintf(errmsg, "[!] not supported with '%s'", args[cur_arg]);
|
||||
goto error;
|
||||
}
|
||||
if (!*(args[cur_arg+1])) {
|
||||
memprintf(errmsg, "'%s' expects a string as argument", args[cur_arg]);
|
||||
goto error;
|
||||
}
|
||||
if (strcasecmp(args[cur_arg+1], "L7TOUT") == 0)
|
||||
tout_st = HCHK_STATUS_L7TOUT;
|
||||
else if (strcasecmp(args[cur_arg+1], "L6TOUT") == 0)
|
||||
tout_st = HCHK_STATUS_L6TOUT;
|
||||
else if (strcasecmp(args[cur_arg+1], "L4TOUT") == 0)
|
||||
tout_st = HCHK_STATUS_L4TOUT;
|
||||
else {
|
||||
memprintf(errmsg, "'%s' only supports 'L4TOUT', 'L6TOUT' or 'L7TOUT' status (got '%s').",
|
||||
args[cur_arg], args[cur_arg+1]);
|
||||
goto error;
|
||||
}
|
||||
cur_arg++;
|
||||
}
|
||||
else {
|
||||
memprintf(errmsg, "'only supports min-recv, '[!]binary', '[!]string', '[!]rstring', '[!]rbinary'"
|
||||
" or comment but got '%s' as argument.", args[cur_arg]);
|
||||
@ -4602,6 +4657,8 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str
|
||||
chk->expect.min_recv = min_recv;
|
||||
chk->expect.inverse = inverse;
|
||||
chk->expect.with_capture = with_capture;
|
||||
chk->expect.err_status = err_st;
|
||||
chk->expect.tout_status = tout_st;
|
||||
|
||||
switch (chk->expect.type) {
|
||||
case TCPCHK_EXPECT_STRING:
|
||||
|
Loading…
Reference in New Issue
Block a user