From 7267f78ebeced002bcbf0c9a4a631f2797da229f Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Tue, 1 Feb 2022 16:08:50 +0100 Subject: [PATCH] MINOR: mworker/cli: set expert/experimental mode from the CLI Allow to set the master CLI in expert or experimental mode. No command within the master are unlocked yet, but it gives the ability to send expert or experimental commands to the workers. echo "@1; experimental-mode on; del server be1/s2" | socat /var/run/haproxy.master - echo "experimental-mode on; @1 del server be1/s2" | socat /var/run/haproxy.master - --- doc/management.txt | 14 ++++++++++++++ include/haproxy/stream-t.h | 6 +++--- src/cli.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/doc/management.txt b/doc/management.txt index b9b7ebdfb..5bcdd1777 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -1941,6 +1941,13 @@ experimental-mode [on|off] development. These features are currently not stable and should be used with care. They may be subject to breaking changes across versions. + When used from the master CLI, this command shouldn't be prefixed, as it will + set the mode for any worker when connecting to its CLI. + + Example: + echo "@1; experimental-mode on; del server be1/s2" | socat /var/run/haproxy.master - + echo "experimental-mode on; @1 del server be1/s2" | socat /var/run/haproxy.master - + expert-mode [on|off] This command is similar to experimental-mode but is used to toggle the expert mode. @@ -1953,6 +1960,13 @@ expert-mode [on|off] This command is only accessible in admin level. Changing to another level automatically resets the expert mode. + When used from the master CLI, this command shouldn't be prefixed, as it will + set the mode for any worker when connecting to its CLI. + + Example: + echo "@1; expert-mode on; debug dev exit 1" | socat /var/run/haproxy.master - + echo "expert-mode on; @1 debug dev exit 1" | socat /var/run/haproxy.master - + get map get acl Lookup the value in the map or in the ACL . or diff --git a/include/haproxy/stream-t.h b/include/haproxy/stream-t.h index f942823de..e44d2ac60 100644 --- a/include/haproxy/stream-t.h +++ b/include/haproxy/stream-t.h @@ -83,10 +83,10 @@ #define SF_WEBSOCKET 0x00400000 /* websocket stream */ /* flags for the proxy of the master CLI */ -/* 0x1.. to 0x3 are reserved for ACCESS_LVL_MASK */ +/* 0x0001.. to 0x8000 are reserved for ACCESS_* flags from cli-t.h */ -#define PCLI_F_PROMPT 0x4 -#define PCLI_F_PAYLOAD 0x8 +#define PCLI_F_PROMPT 0x10000 +#define PCLI_F_PAYLOAD 0x20000 struct hlua; struct proxy; diff --git a/src/cli.c b/src/cli.c index 16ddf0526..841a88dc9 100644 --- a/src/cli.c +++ b/src/cli.c @@ -1751,6 +1751,10 @@ static int cli_parse_expert_experimental_mode(char **args, char *payload, struct char *level_str; char *output = NULL; + /* this will ask the applet to not output a \n after the command */ + if (*args[1] && *args[2] && strcmp(args[2], "-") == 0) + appctx->st1 |= APPCTX_CLI_ST1_NOLF; + if (!cli_has_level(appctx, ACCESS_LVL_ADMIN)) return 1; @@ -2262,6 +2266,27 @@ int pcli_find_and_exec_kw(struct stream *s, char **args, int argl, char **errmsg s->pcli_flags &= ~ACCESS_LVL_MASK; s->pcli_flags |= ACCESS_LVL_USER; return argl; + + } else if (strcmp(args[0], "expert-mode") == 0) { + if (!pcli_has_level(s, ACCESS_LVL_ADMIN)) { + memprintf(errmsg, "Permission denied!\n"); + return -1; + } + + s->pcli_flags &= ~ACCESS_EXPERT; + if ((argl > 1) && (strcmp(args[1], "on") == 0)) + s->pcli_flags |= ACCESS_EXPERT; + return argl; + + } else if (strcmp(args[0], "experimental-mode") == 0) { + if (!pcli_has_level(s, ACCESS_LVL_ADMIN)) { + memprintf(errmsg, "Permission denied!\n"); + return -1; + } + s->pcli_flags &= ~ACCESS_EXPERIMENTAL; + if ((argl > 1) && (strcmp(args[1], "on") == 0)) + s->pcli_flags |= ACCESS_EXPERIMENTAL; + return argl; } return 0; @@ -2410,6 +2435,15 @@ int pcli_parse_request(struct stream *s, struct channel *req, char **errmsg, int } if (ret > 1) { + if (s->pcli_flags & ACCESS_EXPERIMENTAL) { + ci_insert_line2(req, 0, "experimental-mode on -", strlen("experimental-mode on -")); + ret += strlen("experimental-mode on -") + 2; + } + if (s->pcli_flags & ACCESS_EXPERT) { + ci_insert_line2(req, 0, "expert-mode on -", strlen("expert-mode on -")); + ret += strlen("expert-mode on -") + 2; + } + if (pcli_has_level(s, ACCESS_LVL_ADMIN)) { goto end; } else if (pcli_has_level(s, ACCESS_LVL_OPER)) {