diff options
author | John Southworth <john.southworth@vyatta.com> | 2011-08-02 12:30:41 -0500 |
---|---|---|
committer | John Southworth <john.southworth@vyatta.com> | 2011-08-02 12:30:41 -0500 |
commit | 61f8641e6cbb031b01118f460faa263dcbc19f2d (patch) | |
tree | f6916c095b49388bbb6d375fc454a3aec06f158f /functions/interpreter/vyatta-cfg-run | |
parent | 3276c3666befbf0d578065d861046d59b109fa93 (diff) | |
download | vyatta-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-run | 621 |
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 +} |