MINOR: checks: Add an option to set success status of tcp-check expect rules

It is now possible to specified the healthcheck status to use on success of a
tcp-check rule, if it is the last evaluated rule. The option "ok-status"
supports "L4OK", "L6OK", "L7OK" and "L7OKC" status.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index c6b6cf4..71f8852 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -9872,7 +9872,8 @@
   See also : "option tcp-check", "tcp-check send", "tcp-check expect"
 
 
-tcp-check expect [min-recv <int>] [error-status <st>] [tout-status <st>]
+tcp-check expect [min-recv <int>]
+                 [ok-status <st>] [error-status <st>] [tout-status <st>]
                  [on-success <fmt>] [on-error <fmt>] [status-code <expr>]
                  [!] <match> <pattern>
   Specify data to be collected and analyzed during a generic health check
@@ -9898,6 +9899,14 @@
               the match. Spaces are allowed between the exclamation mark and the
               keyword. See below for more details on the supported keywords.
 
+    ok-status <st>     is optional and can be used to set the check status if
+                       the expect rule is successfully evaluated and if it is
+                       the last rule in the tcp-check ruleset. "L7OK", "L7OKC",
+                       "L6OK" and "L4OK" are supported and may be used to set,
+                       respectively, HCHK_STATUS_L7OK, HCHK_STATUS_L7OKCD,
+                       HCHK_STATUS_L6OK or HCHK_STATUS_L4OK success status.
+                        By default "L7OK" is used.
+
     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
@@ -9905,7 +9914,7 @@
                        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
+    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,
diff --git a/include/types/checks.h b/include/types/checks.h
index 2b17125..941fd2e 100644
--- a/include/types/checks.h
+++ b/include/types/checks.h
@@ -275,6 +275,7 @@
 	int min_recv;                   /* Minimum amount of data before an expect can be applied. (default: -1, ignored) */
 	struct list onerror_fmt;        /* log-format string to use as comment on error */
 	struct list onsuccess_fmt;      /* log-format string to use as comment on success (if last rule) */
+	enum healthcheck_status ok_status;   /* The healthcheck status to use on success (default: L7OKD) */
 	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 sample_expr *status_expr; /* sample expr to determine the check status code */
diff --git a/src/checks.c b/src/checks.c
index aacaf61..afa108b 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -2452,7 +2452,7 @@
 	 * FIXME : it can be cool to use MySQL Version for other purpose,
 	 * like mark as down old MySQL server.
 	 */
-	set_server_check_status(check, HCHK_STATUS_L7OKD, b_peek(&check->bi, 5));
+	set_server_check_status(check, rule->expect.ok_status, b_peek(&check->bi, 5));
 
   out:
 	free_trash_chunk(msg);
@@ -2536,7 +2536,7 @@
 		goto error;
 	}
 
-	set_server_check_status(check, HCHK_STATUS_L7OKD, "Success");
+	set_server_check_status(check, rule->expect.ok_status, "Success");
 
   out:
 	free_trash_chunk(msg);
@@ -2578,7 +2578,7 @@
 		goto error;
 	}
 
-	set_server_check_status(check, HCHK_STATUS_L7OKD, "SPOA server is ok");
+	set_server_check_status(check, rule->expect.ok_status, "SPOA server is ok");
 
   out:
 	free_trash_chunk(msg);
@@ -3104,7 +3104,7 @@
 static enum tcpcheck_eval_ret tcpcheck_eval_expect(struct check *check, struct tcpcheck_rule *rule, int last_read)
 {
 	enum tcpcheck_eval_ret ret = TCPCHK_EVAL_CONTINUE;
-	struct tcpcheck_expect *expect = &check->current_step->expect;
+	struct tcpcheck_expect *expect = &rule->expect;
 	struct buffer *msg = NULL;
 	int match;
 
@@ -3391,9 +3391,11 @@
 		msg = alloc_trash_chunk();
 		if (msg)
 			tcpcheck_onsuccess_message(msg, check, check->current_step, ist(NULL));
+		set_server_check_status(check, check->current_step->expect.ok_status, (msg ? b_head(msg) : "(tcp-check)"));
+		free_trash_chunk(msg);
 	}
-	set_server_check_status(check, HCHK_STATUS_L7OKD, (msg ? b_head(msg) : "(tcp-check)"));
-	free_trash_chunk(msg);
+	else
+		set_server_check_status(check, HCHK_STATUS_L7OKD, "(tcp-check)");
 
   out_end_tcpcheck:
 	if ((conn && conn->flags & CO_FL_ERROR) || (cs && cs->flags & CS_FL_ERROR))
@@ -3741,6 +3743,7 @@
 	expect->type = TCPCHK_EXPECT_STRING;
 	LIST_INIT(&expect->onerror_fmt);
 	LIST_INIT(&expect->onsuccess_fmt);
+	expect->ok_status = HCHK_STATUS_L7OKD;
 	expect->err_status = HCHK_STATUS_L7RSP;
 	expect->tout_status = HCHK_STATUS_L7TOUT;
 	expect->string = strdup(str);
@@ -4660,6 +4663,7 @@
 	struct sample_expr *status_expr = NULL;
 	char *str, *on_success_msg, *on_error_msg, *comment, *pattern;
 	enum tcpcheck_expect_type type = TCPCHK_EXPECT_UNDEF;
+	enum healthcheck_status ok_st = HCHK_STATUS_L7OKD;
 	enum healthcheck_status err_st = HCHK_STATUS_L7RSP;
 	enum healthcheck_status tout_st = HCHK_STATUS_L7TOUT;
 	long min_recv = -1;
@@ -4781,6 +4785,30 @@
 				memprintf(errmsg, "out of memory");
 				goto error;
 			}
+		}
+		else if (strcmp(args[cur_arg], "ok-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], "L7OK") == 0)
+				ok_st = HCHK_STATUS_L7OKD;
+			else if (strcasecmp(args[cur_arg+1], "L7OKC") == 0)
+				ok_st = HCHK_STATUS_L7OKCD;
+			else if (strcasecmp(args[cur_arg+1], "L6OK") == 0)
+				ok_st = HCHK_STATUS_L6OK;
+			else if (strcasecmp(args[cur_arg+1], "L4OK") == 0)
+				ok_st = HCHK_STATUS_L4OK;
+			else  {
+				memprintf(errmsg, "'%s' only supports 'L4OK', 'L6OK', 'L7OK' or 'L7OKC' status (got '%s').",
+					  args[cur_arg], args[cur_arg+1]);
+				goto error;
+			}
+			cur_arg++;
 		}
 		else if (strcmp(args[cur_arg], "error-status") == 0) {
 			if (in_pattern) {
@@ -4899,6 +4927,7 @@
 	chk->expect.min_recv = min_recv;
 	chk->expect.inverse = inverse;
 	chk->expect.with_capture = with_capture;
+	chk->expect.ok_status = ok_st;
 	chk->expect.err_status = err_st;
 	chk->expect.tout_status = tout_st;
 	chk->expect.status_expr = status_expr; status_expr = NULL;
@@ -5266,7 +5295,7 @@
 	LIST_ADDQ(&rs->rules, &chk->list);
 
 	chk = parse_tcpcheck_expect((char *[]){"tcp-check", "expect", "rbinary", "^1[56]",
-				                "min-recv", "5",
+				                "min-recv", "5", "ok-status", "L6OK",
 				                "error-status", "L6RSP", "tout-status", "L6TOUT",
 				                ""},
 		                    1, curpx, &rs->rules, file, line, &errmsg);