summaryrefslogtreecommitdiff
path: root/functions/interpreter/vyatta-cfg-run
diff options
context:
space:
mode:
authorJohn Southworth <john.southworth@vyatta.com>2011-08-02 12:30:41 -0500
committerJohn Southworth <john.southworth@vyatta.com>2011-08-02 12:30:41 -0500
commit61f8641e6cbb031b01118f460faa263dcbc19f2d (patch)
treef6916c095b49388bbb6d375fc454a3aec06f158f /functions/interpreter/vyatta-cfg-run
parent3276c3666befbf0d578065d861046d59b109fa93 (diff)
downloadvyatta-cfg-61f8641e6cbb031b01118f460faa263dcbc19f2d.tar.gz
vyatta-cfg-61f8641e6cbb031b01118f460faa263dcbc19f2d.zip
Reorganize the bash completion and command interpreter scripts into easier to manage chunks. Command interpreter is now in vyatta-cfg-run and common functions have been moved to vyatta-op
Diffstat (limited to 'functions/interpreter/vyatta-cfg-run')
-rw-r--r--functions/interpreter/vyatta-cfg-run621
1 files changed, 621 insertions, 0 deletions
diff --git a/functions/interpreter/vyatta-cfg-run b/functions/interpreter/vyatta-cfg-run
new file mode 100644
index 0000000..c226e74
--- /dev/null
+++ b/functions/interpreter/vyatta-cfg-run
@@ -0,0 +1,621 @@
+# vyatta configuration mode command interpreter functions
+
+# **** License ****
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# A copy of the GNU General Public License is available as
+# `/usr/share/common-licenses/GPL' in the Debian GNU/Linux distribution
+# or on the World Wide Web at `http://www.gnu.org/copyleft/gpl.html'.
+# You can also obtain it by writing to the Free Software Foundation,
+# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+# Author: Vyatta
+# Description: Command interpreter functions for config mode
+#
+# **** End License ****
+
+### Top level commands and help ###
+_vyatta_cfg_cmds=( "confirm" \
+ "comment" \
+ "commit" \
+ "commit-confirm" \
+ "compare" \
+ "copy" \
+ "delete" \
+ "discard" \
+ "edit" \
+ "exit" \
+ "load" \
+ "loadkey" \
+ "merge" \
+ "rename" \
+ "rollback" \
+ "run" \
+ "save" \
+ "set" \
+ "show" )
+_vyatta_cfg_helps=( \
+ "Confirm prior commit-confirm" \
+ "Add comment to this configuration element" \
+ "Commit the current set of changes" \
+ "Commit the current set of changes with 'confirm' required" \
+ "Compare configuration revisions" \
+ "Copy a configuration element" \
+ "Delete a configuration element" \
+ "Discard uncommitted changes" \
+ "Edit a sub-element" \
+ "Exit from this configuration level" \
+ "Load configuration from a file and replace running configuration" \
+ "Load user SSH key from a file" \
+ "Load configuration from a file and merge running configuration" \
+ "Rename a configuration element" \
+ "Rollback to a prior config revision (requires reboot)" \
+ "Run an operational-mode command" \
+ "Save configuration to a file" \
+ "Set the value of a parameter or create a new element" \
+ "Show the configuration (default values may be suppressed)" \
+ )
+### End Top level commands and help ###
+
+vyatta_cfg_expand_top_level () {
+ local cmd=$1
+ local -a filtered_cmds=()
+ get_prefix_filtered_list ${cmd} _vyatta_cfg_cmds filtered_cmds
+ local found
+ is_elem_of "${cmd}" _vyatta_cfg_cmds
+ found=$?
+ local fcmd
+ if [[ "${#filtered_cmds[@]}" == "1" || "$found" == "0" ]]; then
+ if [[ "${#filtered_cmds[@]}" == "1" ]]; then
+ fcmd=${filtered_cmds[0]}
+ else
+ fcmd=$cmd
+ fi
+ else
+ fcmd=$cmd
+ fi
+ echo $fcmd
+}
+
+### Top level command wrappers ###
+vyatta_config_show ()
+{
+ local -a opts=()
+ local -a args=()
+ for arg in "$@"; do
+ if [ "$arg" == "-all" ]; then
+ opts+=('--show-show-defaults')
+ else
+ args+=("$arg")
+ fi
+ done
+ cli-shell-api "${opts[@]}" -- showCfg "${args[@]}" \
+ | eval "${VYATTA_PAGER:-cat}"
+}
+
+vyatta_config_commit ()
+{
+ if ! vyatta_cli_shell_api sessionChanged; then
+ echo "No configuration changes to commit"
+ return 1;
+ fi
+ local comment="commit"
+ local next=0
+ local -a args=()
+ for arg in "$@"; do
+ if [ "$next" == "1" ]; then
+ comment=$arg
+ next=0;
+ elif [ "$arg" == "comment" ]; then
+ next=1
+ elif [ "$arg" == "confirm" ]; then
+ echo Use commit-confirm command
+ return 1;
+ else
+ args[${#args[@]}]="$arg"
+ fi
+ done
+
+ export COMMIT_COMMENT="$comment"
+ export COMMIT_VIA=cli
+ /opt/vyatta/sbin/my_commit "${args[@]}" 2>&1
+ unset COMMIT_VIA
+ unset COMMIT_COMMENT
+}
+
+vyatta_config_commit-confirm ()
+{
+ if ! vyatta_cli_shell_api sessionChanged; then
+ echo "No configuration changes to commit"
+ return 1;
+ fi
+ local -a args=()
+ local first=1
+ local minutes=10
+ for arg in "$@"; do
+ if [ "$first" = "1" ]; then
+ if [[ $arg = *[[:digit:]]* ]]; then
+ minutes=$arg
+ else
+ args[${#args[@]}]="$arg"
+ fi
+ first=0
+ else
+ args[${#args[@]}]="$arg"
+ fi
+ done
+ cmd="${vyatta_sbindir}/vyatta-config-mgmt.pl --action=commit-confirm \
+ --minutes=$minutes"
+ eval "sudo sg vyattacfg \"$cmd\" "
+ if [ $? = 0 ]; then
+ commit "$@"
+ fi
+}
+
+vyatta_config_confirm ()
+{
+ ${vyatta_sbindir}/vyatta-config-mgmt.pl --action=confirm
+}
+
+vyatta_config_compare ()
+{
+ local -a comp=( "saved" )
+ local -a filtered=()
+ get_prefix_filtered_list $1 comp filtered
+ if [[ "${filtered[0]}" == "saved" ]]; then
+ cli-shell-api showConfig --show-cfg1 /config/config.boot --show-cfg2 @WORKING --show-context-diff
+ else
+ ${vyatta_sbindir}/vyatta-config-mgmt.pl --action=diff "$@" | eval "${VYATTA_PAGER:-cat}"
+ fi
+}
+
+vyatta_config_save ()
+{
+ if vyatta_cli_shell_api sessionChanged; then
+ echo -e "Warning: you have uncommitted changes that will not be saved.\n"
+ fi
+ # return to top level.
+ reset_edit_level
+ # transform individual args into quoted strings
+ local arg=''
+ local save_cmd="${vyatta_sbindir}/vyatta-save-config.pl"
+ for arg in "$@"; do
+ save_cmd+=" '$arg'"
+ done
+ eval "sudo sg vyattacfg \"umask 0002 ; $save_cmd\""
+ vyatta_cli_shell_api unmarkSessionUnsaved
+}
+
+reboot ()
+{
+ echo "Exit from configure mode before rebooting."
+}
+
+vyatta_config_rollback ()
+{
+ if [ $# != 1 ]; then
+ echo "Error: must include a revision # to rollback to"
+ return 1;
+ fi
+ ${vyatta_sbindir}/vyatta-config-mgmt.pl --action=rollback --revnum "$@"
+}
+
+shutdown ()
+{
+ echo "Exit from configure mode before shutting down system."
+}
+
+reset_edit_level ()
+{
+ vyatta_cli_shell_api getEditResetEnv
+ return $?
+}
+
+vyatta_config_load ()
+{
+ # don't load if there are uncommitted changes.
+ if vyatta_cli_shell_api sessionChanged; then
+ echo "Cannot load: configuration modified."
+ echo "Commit or discard the changes before loading a config file."
+ return 1
+ fi
+ # return to top level.
+ reset_edit_level
+ ${vyatta_sbindir}/vyatta-load-config.pl "$@"
+}
+
+vyatta_config_merge ()
+{
+ # don't load if there are uncommitted changes.
+ if vyatta_cli_shell_api sessionChanged; then
+ echo "Cannot load: configuration modified."
+ echo "Commit or discard the changes before loading a config file."
+ return 1
+ fi
+ # return to top level.
+ reset_edit_level
+ ${vyatta_sbindir}/vyatta-load-config.pl "$@" --merge
+}
+
+top ()
+{
+ if vyatta_cli_shell_api editLevelAtRoot; then
+ echo "Already at the top level"
+ return 0
+ fi
+
+ # go to the top level.
+ reset_edit_level
+}
+
+vyatta_config_edit ()
+{
+ vyatta_cli_shell_api getEditEnv "$@"
+ return $?
+}
+
+up ()
+{
+ vyatta_cli_shell_api getEditUpEnv "$@"
+ return $?
+}
+
+really_exit()
+{
+
+ if vyatta_cli_shell_api sessionUnsaved; then
+ echo "Warning: configuration changes have not been saved."
+ fi
+ vyatta_cli_shell_api teardownSession
+ unset _OFR_CONFIGURE
+ builtin exit 0
+}
+
+vyatta_config_exit ()
+{
+ local discard
+ local -a comp=( "discard" )
+ local -a filtered=()
+ get_prefix_filtered_list $1 comp filtered
+ if [ $# == 0 ]; then
+ discard=0
+ elif [ $# == 1 ] && [ "${filtered[0]}" == "discard" ]; then
+ discard=1
+ else
+ echo "Invalid argument \"$*\" for 'exit'"
+ return 1
+ fi
+
+ if vyatta_cli_shell_api editLevelAtRoot; then
+ # we are at the root level. check if we can really exit.
+ if vyatta_cli_shell_api sessionChanged; then
+ if (( ! discard )); then
+ echo "Cannot exit: configuration modified."
+ echo "Use 'exit discard' to discard the changes and exit."
+ return 1
+ fi
+ fi
+ really_exit
+ fi
+
+ # "exit" to the root level.
+ reset_edit_level
+}
+
+# run op mode commands
+vyatta_config_run ()
+{
+ if [ $# == 0 ]; then
+ echo Incomplete command
+ return 1
+ fi
+ /opt/vyatta/bin/vyatta-op-cmd-wrapper $@
+}
+
+### End Top level command wrappers ###
+
+### Top level wrappers ###
+vyatta_cfg_cmd_run ()
+{
+ local cmd=$1
+ local -a args=( "$@" )
+ local output=''
+ if [[ "$cmd" == "edit" ]]; then
+ vyatta_config_edit "${@:2}"
+ elif [[ "$cmd" == "show" ]]; then
+ vyatta_config_show "${@:2}"
+ else
+ cmd="/opt/vyatta/sbin/my_$cmd"
+ output=$(eval "$cmd ${args[@]:1}")
+ fi
+ vyatta_cfg_print_output "$output"
+}
+
+vyatta_cfg_print_output ()
+{
+ local output=$1
+ if [[ ! -z "${output}" ]];then
+ output=$(echo "$output" | sed -e 's/^/ /')
+ echo -ne "\n${output}\n\n" | eval "${VYATTA_PAGER:-cat}"
+ fi
+}
+
+vyatta_cfg_validate_cmd ()
+{
+ local cmd=$1
+ local -a expanded_api_args=( "$@" )
+ local path=''
+ local opath=''
+ for arg in "${expanded_api_args[@]:1}"; do
+ if [[ "$path" == '' ]]; then
+ path="$arg"
+ else
+ path="$path $arg"
+ fi
+ if ! cli-shell-api validateTmplPath ${path}; then
+ _cli_shell_api_comp_values=()
+ vyatta_cli_shell_api getCompletionEnv $cmd ${path}
+ if [[ "${#_cli_shell_api_comp_values[@]}" != "1"
+ && "${#_cli_shell_api_comp_values[@]}" != "0" ]]; then
+ local -a _get_help_text_items=( "${_cli_shell_api_hitems[@]}" )
+ local -a _get_help_text_helps=( "${_cli_shell_api_hstrs[@]}" )
+ local vyatta_help_text=''
+ if [[ $opath == '' ]]; then
+ echo -ne "\n Configuation path: [$arg] is ambiguous\n"
+ else
+ echo -ne "\n Configuation path: $opath [$arg] is ambiguous\n"
+ fi
+ get_help_text
+ echo -e "$vyatta_help_text\n" | sed 's/^P/ P/'
+ echo -e " ${cmd^} failed\n"
+ break
+ else
+ if [[ $opath == '' ]]; then
+ echo -ne "\n Configuation path: [$arg] is not valid\n ${cmd^} failed\n\n"
+ else
+ echo -ne "\n Configuation path: $opath [$arg] is not valid\n ${cmd^} failed\n\n"
+ fi
+ break
+ fi
+ else
+ opath=$path
+ fi
+ done
+}
+
+vyatta_config_copy ()
+{
+ local cmd=$1
+ if [[ "${#@}" == "1" ]]; then
+ vyatta_cfg_cmd_run $cmd
+ return
+ fi
+ local -a args=( "$@" )
+ local -a param1=( "$cmd" ${args[@]:1:2} )
+ local -a param2=( "$cmd" ${args[@]:4:5} )
+ local editlvl=$(cli-shell-api getEditLevelStr)
+ expanded_api_args=( )
+ vyatta_config_expand_compwords "${param1[@]}"
+ param1=( "${expanded_api_args[@]}" )
+ expanded_api_args=( )
+ vyatta_config_expand_compwords "${param2[@]}"
+ param2=( "${expanded_api_args[@]}" )
+ if [[ "${args[3]}" != "to" ]]; then
+ echo -ne "\n Invalid command: $cmd ${param1[@]:1} ${args[3]} ${param2[@]:1}\n\n"
+ elif cli-shell-api validateTmplPath ${editlvl[*]} "${param1[@]:1}" &&
+ cli-shell-api validateTmplPath ${editlvl[*]} "${param2[@]:1}" ; then
+ cmd="/opt/vyatta/sbin/my_$cmd"
+ output=$(eval "$cmd ${param1[@]:1} to ${param2[@]:1} | sed -e 's/^/ /'")
+ if [[ ! -z "${output}" ]];then
+ echo -ne "\n${output}\n\n"
+ fi
+ else
+ if ! cli-shell-api validateTmplPath ${editlvl[*]} "${param1[@]:1}"; then
+ _cli_shell_api_comp_values=()
+ vyatta_cli_shell_api getCompletionEnv $cmd ${param1[1]}
+ if [[ "${#_cli_shell_api_comp_values[@]}" != "1"
+ && "${#_cli_shell_api_comp_values[@]}" != "0" ]]; then
+ echo -ne "\n Ambiguous command: $cmd [${param1[1]}]\n"
+ echo -ne "\n Possible completions: ${_cli_shell_api_comp_values[@]}\n\n"
+ else
+ echo -ne "\n Invalid command: $cmd [${param1[1]}]\n\n"
+ fi
+ elif ! cli-shell-api validateTmplPath ${editlvl[*]} "${param1[@]:2}"; then
+ _cli_shell_api_comp_values=()
+ vyatta_cli_shell_api getCompletionEnv $cmd "${param2[1]}"
+ if [[ "${#_cli_shell_api_comp_values[@]}" != "1"
+ && "${#_cli_shell_api_comp_values[@]}" != "0" ]]; then
+ echo -ne "\n Ambiguous command: $cmd ${param2[@]:1} to [${param2[1]}]\n"
+ echo -ne "\n Possible completions: ${_cli_shell_api_comp_values[@]}\n\n"
+ else
+ echo -ne "\n Invalid command: $cmd ${param1[@]:1} to [${param2[1]}]\n\n"
+ fi
+ else
+ echo -ne "\n Invalid command: $cmd ${param1[@]:1} to ${param2[@]:1}\n\n"
+ fi
+ fi
+}
+
+vyatta_config_comment ()
+{
+ local cmd=$1
+ if [[ "${#@}" == "1" ]]; then
+ vyatta_cfg_cmd_run $cmd
+ return
+ fi
+ # change the ifs so we can extract the entire comment
+ local OIFS=$IFS
+ local IFS='---'
+ local -a args=( "$@" )
+ # extract the comment
+ local comment="'${args[$[${#args[@]}-1]]}'"
+ args=( "${args[@]:0:$[${#args[@]}-1]}" )
+ IFS=$OIFS
+ local -a expanded_api_args=()
+ # expand the comment command
+ local editlvl=$(cli-shell-api getEditLevelStr)
+ vyatta_config_expand_compwords "${args[@]}"
+ if [[ "$#" != "${#expanded_api_args[@]}" ]]; then
+ expanded_api_args+=( $comment )
+ fi
+ # use the standard run function with the comment expansion
+ vyatta_cfg_cmd_run "${expanded_api_args[@]}"
+}
+
+vyatta_cfg_cmd ()
+{
+ # commands that need expanded paths get called through here
+ local cmd=$1
+ if [[ "$#" == "1" ]]; then
+ vyatta_cfg_cmd_run $cmd
+ return
+ fi
+ # Note: the below code is to account for quoted strings as
+ # leaf node parameter
+ # change the ifs so we can extract the entire last element
+ local OIFS=$IFS
+ local IFS='---'
+ local -a args=( "$@" )
+ local lastelem="${args[$[${#args[@]}-1]]}"
+ args=( "${args[@]:0:$[${#args[@]}-1]}" )
+ IFS=$OIFS
+ local -a lastelem_arr=( $lastelem )
+ #if there is only one last element don't quote it
+ if [[ "${#lastelem_arr[@]}" == "1" ]]; then
+ args+=( "$lastelem" )
+ else
+ lastelem="'$lastelem'"
+ fi
+ local -a expanded_api_args=()
+ local editlvl=$(cli-shell-api getEditLevelStr)
+ vyatta_config_expand_compwords ${args[@]}
+ if cli-shell-api validateTmplPath ${editlvl[*]} "${expanded_api_args[@]:1}"; then
+ # if we have a valid command append the last parameter and run it
+ if [[ "$#" != "${#expanded_api_args[@]}" ]]; then
+ expanded_api_args+=( $lastelem )
+ fi
+ vyatta_cfg_cmd_run "${expanded_api_args[@]}"
+ else
+ # find broken portion of command
+ vyatta_cfg_validate_cmd "${expanded_api_args[@]}"
+ fi
+}
+### Top level wrappers ###
+
+### Main run command ###
+vyatta_cfg_run ()
+{
+ # validate top level command and execute proper function
+ local cmd=$1
+ local -a args=( "$@" )
+ local -a filtered_cmds
+ get_prefix_filtered_list $cmd _vyatta_cfg_cmds filtered_cmds
+ local found
+ is_elem_of "${cmd}" _vyatta_cfg_cmds
+ found=$?
+ if [[ "${#filtered_cmds[@]}" == "0" ]]; then
+ echo -ne "\n Invalid command: [$cmd]\n\n"
+ return 1
+ elif [[ "${#filtered_cmds[@]}" != "1" && "$found" == "1" ]]; then
+ echo -ne "\n Ambiguous command: [$cmd]\n"
+ local -a fitems=()
+ local -a fstrs=()
+ local -a _get_help_text_items=( "${_vyatta_cfg_cmds[@]}" )
+ local -a _get_help_text_helps=( "${_vyatta_cfg_helps[@]}" )
+ get_prefix_filtered_list2 "$cmd" \
+ _get_help_text_items fitems _get_help_text_helps fstrs
+ _get_help_text_items=( "${fitems[@]}" )
+ _get_help_text_helps=( "${fstrs[@]}" )
+ get_help_text
+ echo -e "$vyatta_help_text\n" | sed 's/^P/ P/'
+ return 1
+ fi
+ local fcmd;
+ if is_elem_of "${cmd}" _vyatta_cfg_cmds; then
+ fcmd=$cmd
+ else
+ fcmd=${filtered_cmds[0]}
+ fi
+ case $fcmd in
+ compare) vyatta_config_compare "${@:2}" ;;
+ comment) vyatta_config_comment "${args[@]}" ;; # comment is a special case
+ copy|rename) vyatta_config_copy $fcmd ${@:2} ;; # copy is a special case
+ exit) vyatta_config_exit "${@:2}" ;;
+ run) vyatta_config_run "${@:2}" ;;
+ load) vyatta_config_load "${@:2}" ;;
+ commit) vyatta_config_commit "${@:2}";;
+ confirm) vyatta_config_confirm "${@:2}";;
+ rollback) vyatta_config_rollback "${@:2}";;
+ commit-confirm) vyatta_config_commit-confirm "${@:2}";;
+ compare) vyatta_config_compare "${@:2}";;
+ save) vyatta_config_save "${@:2}" ;;
+ merge) vyatta_config_merge "${@:2}" ;;
+ loadkey) vyatta_config_loadkey "${@:2}";;
+ *) vyatta_cfg_cmd $fcmd "${@:2}" ;; # commands requiring path expansion must go through here
+ esac
+}
+
+### Initalize top level command alias and completion functions
+_vyatta_cfg_init ()
+{
+ # empty and default line compeletion
+ complete -E -F vyatta_config_complete
+ complete -D -F vyatta_config_default_complete
+
+ # create the top level aliases for the unambiguous portions of the commands
+ # this is the only place we need an entire enumerated list of the subcommands
+ for cmd in "${_vyatta_cfg_cmds[@]}"; do
+ for pos in $(seq 1 ${#cmd}); do
+ case ${cmd:0:$pos} in
+ for|do|done|if|fi|case|while|tr )
+ continue ;;
+ *) ;;
+ esac
+ local -a filtered_cmds=()
+ get_prefix_filtered_list ${cmd:0:$pos} _vyatta_cfg_cmds filtered_cmds
+ local found
+ is_elem_of "${cmd:0:$pos}" _vyatta_cfg_cmds
+ found=$?
+ if [[ "${#filtered_cmds[@]}" == "1" || "${cmd:0:$pos}" == "$cmd" || "$found" == "0" ]]; then
+ local fcmd
+ if [[ "${#filtered_cmds[@]}" == "1" ]]; then
+ fcmd=${filtered_cmds[0]}
+ elif is_elem_of "${cmd:0:$pos}" _vyatta_cfg_cmds; then
+ fcmd=${cmd:0:$pos}
+ else
+ fcmd=$cmd
+ fi
+ case $fcmd in
+ save|load|merge)
+ complete -F vyatta_loadsave_complete ${cmd:0:$pos} ;;
+ discard|confirm)
+ ;;
+ run)
+ complete -F vyatta_run_complete ${cmd:0:$pos} ;;
+ loadkey)
+ complete -F vyatta_loadkey_complete ${cmd:0:$pos} ;;
+ compare)
+ complete -F vyatta_compare_complete ${cmd:0:$pos} ;;
+ rollback)
+ complete -F vyatta_rollback_complete ${cmd:0:$pos} ;;
+ commit|commit-confirm)
+ complete -F vyatta_commit_complete ${cmd:0:$pos} ;;
+ *)
+ complete -F vyatta_config_complete ${cmd:0:$pos} ;;
+ esac
+ else
+ complete -F vyatta_config_complete ${cmd:0:$pos}
+ fi
+ eval alias ${cmd:0:$pos}=\'vyatta_cfg_run ${cmd:0:$pos}\'
+ done
+ done
+ shopt -s histverify
+}