]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: cli: implement experimental-mode
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 18 Mar 2021 14:32:53 +0000 (15:32 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 18 Mar 2021 14:37:05 +0000 (15:37 +0100)
Experimental mode is similar to expert-mode. It can be used to access to
features still in development.

doc/management.txt
include/haproxy/cli-t.h
src/cli.c

index ca5d858d0b5f78c2a2ecb656ba16a5e663845b8b..5f88a5d71ccd59c8c982bf9c8388020a0d72bdac 100644 (file)
@@ -1677,11 +1677,21 @@ enable server <backend>/<server>
   This command is restricted and can only be issued on sockets configured for
   level "admin".
 
+experimental-mode [on|off]
+  Without options, this indicates whether the experimental mode is enabled or
+  disabled on the current connection. When passed "on", it turns the
+  experimental mode on for the current CLI connection only. With "off" it turns
+  it off.
+
+  The experimental mode is used to access to extra features still in
+  development. These features are currently not stable and should be used with
+  care. They may be subject to breaking changes accross versions.
+
 expert-mode [on|off]
-  Without options, this indicates whether the expert mode is enabled or
-  disabled on the current connection. When passed "on", it turns the expert
-  mode on for the current CLI connection only. With "off" it turns it off. The
-  expert mode enables displaying of expert commands that can be extremely
+  This command is similar to experimental-mode but is used to toggle the
+  expert mode.
+
+  The expert mode enables displaying of expert commands that can be extremely
   dangerous for the process and which may occasionally help developers collect
   important information about complex bugs. Any misuse of these features will
   likely lead to a process crash. Do not use this option without being invited
@@ -1984,11 +1994,13 @@ show cli level
 
 operator
   Decrease the CLI level of the current CLI session to operator. It can't be
-  increased. It also drops expert mode. See also "show cli level".
+  increased. It also drops expert and experimental mode. See also "show cli
+  level".
 
 user
   Decrease the CLI level of the current CLI session to user. It can't be
-  increased. It also drops expert mode. See also "show cli level".
+  increased. It also drops expert and experimental mode. See also "show cli
+  level".
 
 show activity
   Reports some counters about internal events that will help developers and
index 450781ab5d6929feded00eaa1e62cfe54f58dc5f..3d52f27b4bed4319a3dc20e789a0bc9167ac8be0 100644 (file)
@@ -35,6 +35,7 @@
 #define ACCESS_MASTER       0x0008  /* works with the master (and every other processes) */
 #define ACCESS_MASTER_ONLY  0x0010  /* only works with the master */
 #define ACCESS_EXPERT       0x0020  /* access to dangerous commands reserved to experts */
+#define ACCESS_EXPERIMENTAL 0x0040
 
 /* flags for appctx->st1 */
 #define APPCTX_CLI_ST1_PROMPT  (1 << 0)
index 9aede130998defac94e920304c96c8ae354a36a0..2e4da522fd34484637dca1dad3b86e7e19722446 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -103,7 +103,7 @@ static char *cli_gen_usage_msg(struct appctx *appctx, char * const *args)
        /* first, let's measure the longest match */
        list_for_each_entry(kw_list, &cli_keywords.list, list) {
                for (kw = &kw_list->kw[0]; kw->str_kw[0]; kw++) {
-                       if (kw->level & ~appctx->cli_level & (ACCESS_MASTER_ONLY|ACCESS_EXPERT))
+                       if (kw->level & ~appctx->cli_level & (ACCESS_MASTER_ONLY|ACCESS_EXPERT|ACCESS_EXPERIMENTAL))
                                continue;
                        if ((appctx->cli_level & ~kw->level & (ACCESS_MASTER_ONLY|ACCESS_MASTER)) ==
                            (ACCESS_MASTER_ONLY|ACCESS_MASTER))
@@ -143,7 +143,7 @@ static char *cli_gen_usage_msg(struct appctx *appctx, char * const *args)
        if (args && args[length] && *args[length]) {
                list_for_each_entry(kw_list, &cli_keywords.list, list) {
                        for (kw = &kw_list->kw[0]; kw->str_kw[0]; kw++) {
-                               if (kw->level & ~appctx->cli_level & (ACCESS_MASTER_ONLY|ACCESS_EXPERT))
+                               if (kw->level & ~appctx->cli_level & (ACCESS_MASTER_ONLY|ACCESS_EXPERT|ACCESS_EXPERIMENTAL))
                                        continue;
                                if ((appctx->cli_level & ~kw->level & (ACCESS_MASTER_ONLY|ACCESS_MASTER)) ==
                                    (ACCESS_MASTER_ONLY|ACCESS_MASTER))
@@ -226,9 +226,9 @@ static char *cli_gen_usage_msg(struct appctx *appctx, char * const *args)
                for (kw = &kw_list->kw[0]; kw->str_kw[0]; kw++) {
 
                        /* in a worker or normal process, don't display master-only commands
-                        * nor expert mode commands if not in this mode.
+                        * nor expert/experimental mode commands if not in this mode.
                         */
-                       if (kw->level & ~appctx->cli_level & (ACCESS_MASTER_ONLY|ACCESS_EXPERT))
+                       if (kw->level & ~appctx->cli_level & (ACCESS_MASTER_ONLY|ACCESS_EXPERT|ACCESS_EXPERIMENTAL))
                                continue;
 
                        /* in master don't display commands that have neither the master bit
@@ -730,6 +730,11 @@ static int cli_parse_request(struct appctx *appctx)
                return 0;
        }
 
+       if (kw->level & ~appctx->cli_level & ACCESS_EXPERIMENTAL) {
+               cli_err(appctx, "This command is restricted to experimental mode only.\n");
+               return 0;
+       }
+
        appctx->io_handler = kw->io_handler;
        appctx->io_release = kw->io_release;
 
@@ -1677,29 +1682,45 @@ static int cli_parse_set_lvl(char **args, char *payload, struct appctx *appctx,
                appctx->cli_level &= ~ACCESS_LVL_MASK;
                appctx->cli_level |= ACCESS_LVL_USER;
        }
-       appctx->cli_level &= ~ACCESS_EXPERT;
+       appctx->cli_level &= ~(ACCESS_EXPERT|ACCESS_EXPERIMENTAL);
        return 1;
 }
 
 
-/* parse and set the CLI expert-mode dynamically */
-static int cli_parse_expert_mode(char **args, char *payload, struct appctx *appctx, void *private)
+/* parse and set the CLI expert/experimental-mode dynamically */
+static int cli_parse_expert_experimental_mode(char **args, char *payload, struct appctx *appctx, void *private)
 {
+       int level;
+       char *level_str;
+       char *output = NULL;
+
        if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
                return 1;
 
-       if (!*args[1])
-               return (appctx->cli_level & ACCESS_EXPERT)
-                       ? cli_msg(appctx, LOG_INFO, "expert-mode is ON\n")
-                       : cli_msg(appctx, LOG_INFO, "expert-mode is OFF\n");
+       if (!strcmp(args[0], "expert-mode")) {
+               level = ACCESS_EXPERT;
+               level_str = "expert-mode";
+       }
+       else if (!strcmp(args[0], "experimental-mode")) {
+               level = ACCESS_EXPERIMENTAL;
+               level_str = "experimental-mode";
+       }
+       else {
+               return 1;
+       }
+
+       if (!*args[1]) {
+               memprintf(&output, "%s is %s\n", level_str,
+                         (appctx->cli_level & level) ? "ON" : "OFF");
+               return cli_dynmsg(appctx, LOG_INFO, output);
+       }
 
-       appctx->cli_level &= ~ACCESS_EXPERT;
+       appctx->cli_level &= ~level;
        if (strcmp(args[1], "on") == 0)
-               appctx->cli_level |= ACCESS_EXPERT;
+               appctx->cli_level |= level;
        return 1;
 }
 
-
 int cli_parse_default(char **args, char *payload, struct appctx *appctx, void *private)
 {
        return 0;
@@ -2928,7 +2949,8 @@ static struct cli_kw_list cli_kws = {{ },{
        { { "operator", NULL },  "operator       : lower the level of the current CLI session to operator", cli_parse_set_lvl, NULL, NULL, NULL, ACCESS_MASTER},
        { { "user", NULL },      "user           : lower the level of the current CLI session to user", cli_parse_set_lvl, NULL, NULL, NULL, ACCESS_MASTER},
        { { "_getsocks", NULL }, NULL,  _getsocks, NULL },
-       { { "expert-mode", NULL },  NULL,  cli_parse_expert_mode, NULL }, // not listed
+       { { "expert-mode", NULL },  NULL,  cli_parse_expert_experimental_mode, NULL }, // not listed
+       { { "experimental-mode", NULL },  NULL,  cli_parse_expert_experimental_mode, NULL }, // not listed
        {{},}
 }};