vty: introduce the expert mode and a command to enable it

Some VTY commands are intentionally hidden, e.g. because they might
by relatively dangerous if used in production operation.  We equip
such commands with a special attribute - CMD_ATTR_HIDDEN.

The problem is that neiter they appear in the XML VTY reference,
nor in the online VTY help, so it's a bit tricky to invoke them.
This change introduces so-called 'expert' mode, in which hidden
(but not deprecated) commands are getting visible.

In the (telnet) VTY session, this mode can be activated by passing
an additional argument to well-known 'enable' command:

  OsmoApp> enable ?
    [expert-mode]  Enable the expert mode (show hidden commands)
  OsmoApp> enable expert-mode
  OsmoApp#

so then hidden commands will appear together with all the other
commands.  They will be marked with a special '^' flag:

  OsmoApp# list with-flags
    ^ ...  foo-hidden [expert-mode]
    . ...  foo-regular-one
    ! ...  foo-immediate
    ^ u..  app-hidden-unbelievable

For the XML reference generation, additional API needs to be
introduced.  This will be implemented in subsequent patches.

Change-Id: Ie69c2a19b22fb31d7bd7f6412f0aeac86ea5048f
Related: SYS#4910
diff --git a/tests/vty/vty_transcript_test.c b/tests/vty/vty_transcript_test.c
index abe3702..c9ecf18 100644
--- a/tests/vty/vty_transcript_test.c
+++ b/tests/vty/vty_transcript_test.c
@@ -232,6 +232,23 @@
 	return CMD_SUCCESS;
 }
 
+DEFUN_DEPRECATED(cfg_attr_deprecated,
+		 cfg_attr_deprecated_cmd,
+		 "foo-deprecated",
+		 "This command is deprecated\n")
+{
+	return CMD_WARNING;
+}
+
+DEFUN_HIDDEN(cfg_attr_hidden,
+	     cfg_attr_hidden_cmd,
+	     "foo-hidden [expert-mode]",
+	     "This command is hidden\n"
+	     "But can be seen in the expert mode\n")
+{
+	return CMD_SUCCESS;
+}
+
 DEFUN_ATTR(cfg_attr_immediate, cfg_attr_immediate_cmd,
 	   "foo-immediate",
 	   "Applies immediately\n",
@@ -293,6 +310,15 @@
 	return CMD_SUCCESS;
 }
 
+DEFUN_ATTR_USRATTR(cfg_attr_hidden_app_attr_unbelievable,
+		   cfg_attr_hidden_app_attr_unbelievable_cmd,
+		   CMD_ATTR_HIDDEN, X(TEST_ATTR_UNBELIEVABLE),
+		   "app-hidden-unbelievable",
+		   "Hidden, but still unbelievable help message\n")
+{
+	return CMD_SUCCESS;
+}
+
 static void init_vty_cmds()
 {
 	install_element_ve(&single0_cmd);
@@ -302,6 +328,8 @@
 
 	install_element(CONFIG_NODE, &cfg_attr_test_cmd);
 	install_node(&attr_test_node, NULL);
+	install_element(ATTR_TEST_NODE, &cfg_attr_deprecated_cmd);
+	install_element(ATTR_TEST_NODE, &cfg_attr_hidden_cmd);
 	install_element(ATTR_TEST_NODE, &cfg_attr_immediate_cmd);
 	install_element(ATTR_TEST_NODE, &cfg_attr_node_exit_cmd);
 
@@ -311,6 +339,7 @@
 
 	install_element(ATTR_TEST_NODE, &cfg_app_attr_unbelievable_magnificent_cmd);
 	install_element(ATTR_TEST_NODE, &cfg_app_attr_unbelievable_wonderful_cmd);
+	install_element(ATTR_TEST_NODE, &cfg_attr_hidden_app_attr_unbelievable_cmd);
 }
 
 int main(int argc, char **argv)
diff --git a/tests/vty/vty_transcript_test.vty b/tests/vty/vty_transcript_test.vty
index 2c618d8..7b8241e 100644
--- a/tests/vty/vty_transcript_test.vty
+++ b/tests/vty/vty_transcript_test.vty
@@ -87,6 +87,7 @@
 
 vty_transcript_test> show vty-attributes
   Global attributes:
+    ^  This command is hidden (check expert mode)
     !  This command applies immediately
     @  This command applies on VTY node exit
   Library specific attributes:
@@ -104,7 +105,7 @@
 vty_transcript_test(config)# attribute-test
 
 vty_transcript_test(config-attr-test)# list
-...
+... !foo-(hidden|deprecated)
   foo-immediate
   foo-node-exit
   app-unbelievable
@@ -112,9 +113,10 @@
   app-wonderful
   app-unbelievable-magnificent
   app-unbelievable-wonderful
+... !app-hidden-*
 
 vty_transcript_test(config-attr-test)# list with-flags
-...
+... !foo-(hidden|deprecated)
   ! ...  foo-immediate
   @ ...  foo-node-exit
   . u..  app-unbelievable
@@ -122,3 +124,56 @@
   . ..w  app-wonderful
   . um.  app-unbelievable-magnificent
   . u.w  app-unbelievable-wonderful
+... !app-hidden-*
+
+vty_transcript_test(config-attr-test)# foo-deprecated?
+% There is no matched command.
+vty_transcript_test(config-attr-test)# foo-hidden?
+% There is no matched command.
+vty_transcript_test(config-attr-test)# app-hidden-unbelievable?
+% There is no matched command.
+
+vty_transcript_test(config-attr-test)# end
+vty_transcript_test# disable
+
+vty_transcript_test> enable?
+  enable  Turn on privileged mode command
+vty_transcript_test> enable ?
+  [expert-mode]  Enable the expert mode (show hidden commands)
+
+vty_transcript_test> enable expert-mode
+vty_transcript_test# configure terminal
+vty_transcript_test(config)# attribute-test
+
+vty_transcript_test(config-attr-test)# list
+... !foo-deprected
+  foo-hidden [expert-mode]
+  foo-immediate
+  foo-node-exit
+  app-unbelievable
+  app-magnificent
+  app-wonderful
+  app-unbelievable-magnificent
+  app-unbelievable-wonderful
+  app-hidden-unbelievable
+
+vty_transcript_test(config-attr-test)# list with-flags
+... !foo-deprected
+  ^ ...  foo-hidden [expert-mode]
+  ! ...  foo-immediate
+  @ ...  foo-node-exit
+  . u..  app-unbelievable
+  . .m.  app-magnificent
+  . ..w  app-wonderful
+  . um.  app-unbelievable-magnificent
+  . u.w  app-unbelievable-wonderful
+  ^ u..  app-hidden-unbelievable
+
+vty_transcript_test(config-attr-test)# foo-deprecated?
+% There is no matched command.
+vty_transcript_test(config-attr-test)# foo-hidden?
+  foo-hidden  This command is hidden
+vty_transcript_test(config-attr-test)# foo-hidden ?
+  [expert-mode]  But can be seen in the expert mode
+vty_transcript_test(config-attr-test)# app-hidden-unbelievable?
+  app-hidden-unbelievable  Hidden, but still unbelievable help message