mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-25 04:17:42 +00:00
[MINOR] acl: add srv_is_up() to check that a specific server is up or not
This ACL was missing in complex setups where the status of a remote site has to be considered in switching decisions. Until there, using a server's status in an ACL required to have a dedicated backend, which is a bit heavy when multiple servers have to be monitored.
This commit is contained in:
parent
020534d6f7
commit
0b1cd94c8b
@ -6156,6 +6156,17 @@ src <ip_address>
|
|||||||
src_port <integer>
|
src_port <integer>
|
||||||
Applies to the client's TCP source port. This has a very limited usage.
|
Applies to the client's TCP source port. This has a very limited usage.
|
||||||
|
|
||||||
|
srv_is_up(<server>)
|
||||||
|
srv_is_up(<backend>/<server>)
|
||||||
|
Returns true when the designated server is UP, and false when it is either
|
||||||
|
DOWN or in maintenance mode. If <backend> is omitted, then the server is
|
||||||
|
looked up in the current backend. The function takes no arguments since it
|
||||||
|
is used as a boolean. It is mainly used to take action based on an external
|
||||||
|
status reported via a health check (eg: a geographical site's availability).
|
||||||
|
Another possible use which is more of a hack consists in using dummy servers
|
||||||
|
as boolean variables that can be enabled or disabled from the CLI, so that
|
||||||
|
rules depending on those ACLs can be tweaked in realtime.
|
||||||
|
|
||||||
|
|
||||||
7.5.2. Matching contents at Layer 4
|
7.5.2. Matching contents at Layer 4
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* include/types/acl.h
|
* include/types/acl.h
|
||||||
* This file provides structures and types for ACLs.
|
* This file provides structures and types for ACLs.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
|
* Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include <types/auth.h>
|
#include <types/auth.h>
|
||||||
#include <types/proxy.h>
|
#include <types/proxy.h>
|
||||||
|
#include <types/server.h>
|
||||||
#include <types/session.h>
|
#include <types/session.h>
|
||||||
|
|
||||||
#include <ebmbtree.h>
|
#include <ebmbtree.h>
|
||||||
@ -304,6 +305,7 @@ struct acl_expr {
|
|||||||
union { /* optional argument of the subject (eg: header or cookie name) */
|
union { /* optional argument of the subject (eg: header or cookie name) */
|
||||||
char *str;
|
char *str;
|
||||||
struct userlist *ul;
|
struct userlist *ul;
|
||||||
|
struct server *srv;
|
||||||
} arg;
|
} arg;
|
||||||
int arg_len; /* optional argument length */
|
int arg_len; /* optional argument length */
|
||||||
struct list patterns; /* list of acl_patterns */
|
struct list patterns; /* list of acl_patterns */
|
||||||
|
48
src/acl.c
48
src/acl.c
@ -24,6 +24,7 @@
|
|||||||
#include <proto/acl.h>
|
#include <proto/acl.h>
|
||||||
#include <proto/auth.h>
|
#include <proto/auth.h>
|
||||||
#include <proto/log.h>
|
#include <proto/log.h>
|
||||||
|
#include <proto/proxy.h>
|
||||||
|
|
||||||
#include <ebsttree.h>
|
#include <ebsttree.h>
|
||||||
|
|
||||||
@ -1428,6 +1429,53 @@ acl_find_targets(struct proxy *p)
|
|||||||
|
|
||||||
list_for_each_entry(acl, &p->acl, list) {
|
list_for_each_entry(acl, &p->acl, list) {
|
||||||
list_for_each_entry(expr, &acl->expr, list) {
|
list_for_each_entry(expr, &acl->expr, list) {
|
||||||
|
if (strcmp(expr->kw->kw, "srv_is_up") == 0) {
|
||||||
|
struct proxy *px;
|
||||||
|
struct server *srv;
|
||||||
|
char *pname, *sname;
|
||||||
|
|
||||||
|
if (!expr->arg.str || !*expr->arg.str) {
|
||||||
|
Alert("proxy %s: acl %s %s(): missing server name.\n",
|
||||||
|
p->id, acl->name, expr->kw->kw);
|
||||||
|
cfgerr++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pname = expr->arg.str;
|
||||||
|
sname = strrchr(pname, '/');
|
||||||
|
|
||||||
|
if (sname)
|
||||||
|
*sname++ = '\0';
|
||||||
|
else {
|
||||||
|
sname = pname;
|
||||||
|
pname = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
px = p;
|
||||||
|
if (pname) {
|
||||||
|
px = findproxy(pname, PR_CAP_BE);
|
||||||
|
if (!px) {
|
||||||
|
Alert("proxy %s: acl %s %s(): unable to find proxy '%s'.\n",
|
||||||
|
p->id, acl->name, expr->kw->kw, pname);
|
||||||
|
cfgerr++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
srv = findserver(px, sname);
|
||||||
|
if (!srv) {
|
||||||
|
Alert("proxy %s: acl %s %s(): unable to find server '%s'.\n",
|
||||||
|
p->id, acl->name, expr->kw->kw, sname);
|
||||||
|
cfgerr++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(expr->arg.str);
|
||||||
|
expr->arg_len = 0;
|
||||||
|
expr->arg.srv = srv;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (strstr(expr->kw->kw, "http_auth") == expr->kw->kw) {
|
if (strstr(expr->kw->kw, "http_auth") == expr->kw->kw) {
|
||||||
|
|
||||||
if (!expr->arg.str || !*expr->arg.str) {
|
if (!expr->arg.str || !*expr->arg.str) {
|
||||||
|
@ -1232,6 +1232,24 @@ acl_fetch_nbsrv(struct proxy *px, struct session *l4, void *l7, int dir,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* report in test->flags a success or failure depending on the designated
|
||||||
|
* server's state. There is no match function involved since there's no pattern.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
acl_fetch_srv_is_up(struct proxy *px, struct session *l4, void *l7, int dir,
|
||||||
|
struct acl_expr *expr, struct acl_test *test)
|
||||||
|
{
|
||||||
|
struct server *srv = expr->arg.srv;
|
||||||
|
|
||||||
|
test->flags = ACL_TEST_F_VOL_TEST;
|
||||||
|
if (!(srv->state & SRV_MAINTAIN) &&
|
||||||
|
(!(srv->state & SRV_CHECKED) || (srv->state & SRV_RUNNING)))
|
||||||
|
test->flags |= ACL_TEST_F_SET_RES_PASS;
|
||||||
|
else
|
||||||
|
test->flags |= ACL_TEST_F_SET_RES_FAIL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* set test->i to the number of enabled servers on the proxy */
|
/* set test->i to the number of enabled servers on the proxy */
|
||||||
static int
|
static int
|
||||||
acl_fetch_connslots(struct proxy *px, struct session *l4, void *l7, int dir,
|
acl_fetch_connslots(struct proxy *px, struct session *l4, void *l7, int dir,
|
||||||
@ -1410,6 +1428,7 @@ static struct acl_kw_list acl_kws = {{ },{
|
|||||||
{ "be_conn", acl_parse_int, acl_fetch_be_conn, acl_match_int, ACL_USE_NOTHING },
|
{ "be_conn", acl_parse_int, acl_fetch_be_conn, acl_match_int, ACL_USE_NOTHING },
|
||||||
{ "queue", acl_parse_int, acl_fetch_queue_size, acl_match_int, ACL_USE_NOTHING },
|
{ "queue", acl_parse_int, acl_fetch_queue_size, acl_match_int, ACL_USE_NOTHING },
|
||||||
{ "avg_queue", acl_parse_int, acl_fetch_avg_queue_size, acl_match_int, ACL_USE_NOTHING },
|
{ "avg_queue", acl_parse_int, acl_fetch_avg_queue_size, acl_match_int, ACL_USE_NOTHING },
|
||||||
|
{ "srv_is_up", acl_parse_nothing, acl_fetch_srv_is_up, acl_match_nothing, ACL_USE_NOTHING },
|
||||||
{ NULL, NULL, NULL, NULL },
|
{ NULL, NULL, NULL, NULL },
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user