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)) {