MEDIUM: server: change server ip address from stats socket
New command available on the stats socket to change a server addr using
the command "set server <backend>/<server> addr <ip4|ip6>"
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 897e285..9fbffba 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -14930,6 +14930,9 @@
is passed in number of sessions per second sent to the SSL stack. It applies
before the handshake in order to protect the stack against handshake abuses.
+set server <backend>/<server> addr <ip4 or ip6 address>
+ Replace the current IP address of a server by the one provided.
+
set server <backend>/<server> agent [ up | down ]
Force a server's agent to a new state. This can be useful to immediately
switch a server's state regardless of some slow agent checks for example.
diff --git a/include/proto/server.h b/include/proto/server.h
index 7e32995..64f2327 100644
--- a/include/proto/server.h
+++ b/include/proto/server.h
@@ -95,6 +95,13 @@
const char *weight_str);
/*
+ * Parses addr_str and configures sv accordingly.
+ * Returns NULL on success, error message string otherwise.
+ */
+const char *server_parse_addr_change_request(struct server *sv,
+ const char *addr_str);
+
+/*
* Return true if the server has a zero user-weight, meaning it's in draining
* mode (ie: not taking new non-persistent connections).
*/
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 31bc0ba..cd19279 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -186,7 +186,7 @@
" show table [id]: report table usage stats or dump this table's contents\n"
" get weight : report a server's current weight\n"
" set weight : change a server's weight\n"
- " set server : change a server's state or weight\n"
+ " set server : change a server's state, weight or address\n"
" set table [id] : update or create a table entry's data\n"
" set timeout : change a timeout setting\n"
" set maxconn : change a maxconn setting\n"
@@ -1510,8 +1510,15 @@
appctx->st0 = STAT_CLI_PRINT;
}
}
+ else if (strcmp(args[3], "addr") == 0) {
+ warning = server_parse_addr_change_request(sv, args[4]);
+ if (warning) {
+ appctx->ctx.cli.msg = warning;
+ appctx->st0 = STAT_CLI_PRINT;
+ }
+ }
else {
- appctx->ctx.cli.msg = "'set server <srv>' only supports 'agent', 'health', 'state' and 'weight'.\n";
+ appctx->ctx.cli.msg = "'set server <srv>' only supports 'agent', 'health', 'state', 'weight' and 'addr'.\n";
appctx->st0 = STAT_CLI_PRINT;
}
return 1;
diff --git a/src/server.c b/src/server.c
index 369dd79..2bde246 100644
--- a/src/server.c
+++ b/src/server.c
@@ -802,6 +802,29 @@
return NULL;
}
+/*
+ * Parses <addr_str> and configures <sv> accordingly.
+ * Returns:
+ * - error string on error
+ * - NULL on success
+ */
+const char *server_parse_addr_change_request(struct server *sv,
+ const char *addr_str)
+{
+ unsigned char ip[INET6_ADDRSTRLEN];
+
+ if (inet_pton(AF_INET6, addr_str, ip)) {
+ update_server_addr(sv, ip, AF_INET6, "stats command\n");
+ return NULL;
+ }
+ if (inet_pton(AF_INET, addr_str, ip)) {
+ update_server_addr(sv, ip, AF_INET, "stats command\n");
+ return NULL;
+ }
+
+ return "Could not understand IP address format.\n";
+}
+
int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, struct proxy *defproxy)
{
struct server *newsrv = NULL;