From d618ea2b1a7b9f06e75a877082951ad80fb87dc5 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Fri, 31 Dec 2021 16:32:08 +1100 Subject: [PATCH] newfeature: can now add a new node, but only builtin types newfeature: can now delete nodes --- gnscli.sh | 487 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 304 insertions(+), 183 deletions(-) diff --git a/gnscli.sh b/gnscli.sh index b3796f4..4fc9414 100755 --- a/gnscli.sh +++ b/gnscli.sh @@ -1,9 +1,8 @@ #!/bin/bash -# add node -# issue with json post data +# add appliance +# clean up action output # rename project -# delete node # node stop givesjq error @@ -770,20 +769,31 @@ function runcurlget() { # location api_endpoint(ovname) return $rv } -function runcurldatapost() { # location api_endpoint "curl data" +function runcurldatapost() { # location api_endpoint endpoint_uuid "curl data" local thisapi thisurl curlres rv local loc api_endpoint obname ovmethod + local endpoint_uuid local data="" loc="$1" api_endpoint="$2" - data="$3" + endpoint_uuid="$3" + data="$4" thisapi=$(get $loc api) [[ -z $thisapi ]] && echo "cant find api for '$loc'" && return 1 #thisauthdom=$(get $loc authdomain) -debug -f "data is $data" thisurl="$thisapi/$api_endpoint" + thisurl=${thisurl/\/v2\/appliances/\/v2\/projects\/_CURPROJECT_\/appliances} # special case thisurl=${thisurl/_CURPROJECT_/$curprojid} + if [[ -n $endpoint_uuid ]]; then + thisurl="$thisurl/$endpoint_uuid" + fi +debug -f "loc is $loc" +debug -f "api_endpoint is $api_endpoint" +debug -f "endpoint_uuid is $endpoint_uuid" +debug -f "data is $data" +debug -f "thisapi is $thisapi" +debug -f "thisurl is $thisurl" debug -f "curl -XPOST -sk --header 'Content-type: application/xml' --header 'Accept: application/json' -d \"$data\" $thisurl" set -x @@ -800,8 +810,9 @@ set +x function runcurlaction() { # location api_endpoint(ovname) obname ovmethod ["curl data"] local thisapi thisurl curlres rv #local thisauthdom u p thisauthstr - local loc api_endpoint obname ovmethod + local loc api_endpoint obname ovmethou local data="" + local curlmethod="POST" #local data="" loc="$1" api_endpoint="$2" @@ -822,8 +833,15 @@ debug -f "data is $data" #unset u #unset p - debug -f "curl -XPOST -sk --header 'Content-type: application/xml' --header 'Accept: application/json' -d \"$data\" $thisurl" - curlres=$(curl -XPOST -sk --header 'Content-type: application/xml' --header 'Accept: application/json' -d "$data" $thisurl) + if [[ $GLOBALACTION == "del" ]]; then + curlmethod="DELETE" + else + curlmethod="POST" + fi + + + debug -f "curl -X$curlmethod -sk --header 'Content-type: application/xml' --header 'Accept: application/json' -d \"$data\" $thisurl" + curlres=$(curl -X$curlmethod -sk --header 'Content-type: application/xml' --header 'Accept: application/json' -d "$data" $thisurl) rv=$? [[ $rv -ne 0 ]] && error "curl to $thisurl failed" @@ -876,6 +894,7 @@ function getgnsmethod() { start) echo "start";; stop) echo "stop";; add) echo "";; + del) echo "";; #migrate) echo "migrate";; *) echo @@ -923,8 +942,13 @@ function runaction_loc() { # runaction_loc syd|etc api_endpoint action_name ob_u opts="$*" opts_arr=( $opts ) -debug -f "extrainfo : $extrainfo" -debug -f "remaining opts: $opts" +debug -f "arglist - loc: $loc" +debug -f "arglist - epidx: $epidx" +debug -f "arglist - actionname: $actionname" +debug -f "arglist - ob: $ob" +debug -f "arglist - obname: $obname" +debug -f "arglist - extrainfo : $extrainfo" +debug -f "arglist: remaining opts: $opts" if [[ $actionname == "add" ]]; then curldata=$(makejson "$extrainfo") fi @@ -963,21 +987,35 @@ debug -f "remaining opts: $opts" return 1 fi + debug -f "ABOUT TO CALL CURL FUNCTION...." debug -f "location: ${loc}" debug -f "api endpoint: ${api_endpoint}" debug -f "jq obj: ${jq_obj}" debug -f "actionname: ${actionname} (gns method: '$method')" - debug -f "obname: ${ob}" + debug -f "ob: ${ob}" debug -f "options: ${opts}" debug -f "curldata: ${curldata}" if [[ $action == "add" ]]; then - curlres=$(runcurldatapost $loc $api_endpoint "$curldata" ) + # note: "ob" is empty when adding a builtin node like VPCS + curlres=$(runcurldatapost "$loc" "$api_endpoint" "$ob" "$curldata" ) crv=$? else - curlres=$(runcurlaction $loc $api_endpoint $ob $method "$curldata" ) + curlres=$(runcurlaction "$loc" "$api_endpoint" "$ob" "$method" "$curldata" ) crv=$? fi + + if [[ $curlres =~ $CURLERRORSTRINGS ]]; then + if jq -e . >/dev/null 2>&1 <<< "$curlres"; then + error "curl returned json error:" + echo -en "$RED" >/dev/stderr + echo "$curlres" | jq . | sed -e 's/^/ /' >/dev/stderr + echo -e "$PLAIN" >/dev/stderr + else + error "curl returned error: [$curlres]" + fi + crv=99 + fi if [[ $crv -ne 0 ]]; then rv=1 fi @@ -1144,7 +1182,7 @@ function getbasefilter() { # epidx [regexp_filter] bf="${bf}] ), (.[] | $refilter | [\"_LOCATION_\"" first=1 for x in ${fields[@]}; do - thisdefault="defaultvalue" + thisdefault="not_found" [[ $x == ".status" ]] && thisdefault="project_closed" x=${x//^/ } #bf="${bf}, try(${x}) catch(\"xx\")" @@ -1290,12 +1328,16 @@ debug "opts is $opts" else pids="" while read -r line ; do +debug -f "processing line: [$line]" loc=$(echo "$line" | cut -d, -f1) ob=$(echo "$line" | cut -d, -f2) obuuid=$(echo "$line" | cut -d, -f3) extrainfo=$(echo "$line" | cut -d, -f4-) -debug "extrainfo is: $extrainfo" - runaction_loc $loc $epidx $actionname $obuuid $ob "$extrainfo" $opts > "$TMPDIR/run,$loc,$ob" & +debug -f "--> loc = $loc" +debug -f "--> ob = $ob" +debug -f "--> obuuid = $obuuid" +debug -f "--> extrainfo = $extrainfo" + runaction_loc "$loc" "$epidx" "$actionname" "$obuuid" "$ob" "$extrainfo" $opts > "$TMPDIR/run,$loc,$ob" & pids="$pids $!" done <<< "$targetlist" @@ -1390,6 +1432,7 @@ function validate_action() { # nodes/vms/etv actionname local what acion epidx what="$1" action="$2" + debug "validating action '$action' on obtype '$what'" epidx=$(getepidx $what) [[ $? -ne 0 ]] && return 1 [[ ${ep_validactions[$epidx]} != *\ $action\ * ]] && return 1 @@ -1697,6 +1740,14 @@ function listcommands() { done } +function listcommandaliases() { + local x format + format=" %-12s|%-24s|%-36s${PLAIN}\n" + printf "${UNDERLINE}${BOLD}$format" "Alias" "Command" "Default Args" + for x in ${!cmdalias_src[@]}; do + printf "$format" "${cmdalias_src[$x]}" "${cmdalias_dst[$x]}" "${cmdalias_defaultarg[$x]}" + done +} function generate_random_string() { local segmentlen=5 x str="" thissegment @@ -1752,11 +1803,20 @@ function expand_cmdalias() { # expand_cmdalias "cmd" newcmd_var newargs_var "ar return 1 } +function getnodetypeforadd() { + local nt + nt=$(echo "$1" | tr 'A-Z' 'a-z' | tr ' ' '_') + echo "$nt" + +} + function processcmd() { local cmd arg newarg rv newlocs x err admin idx opts pipe gotargs local whattolist actionname="" actionfilter="" local showerror=0 showerroropt="" - local epidx endpoint newname newtype newtype_uuid + local epidx endpoint addendpoint newname newnodetype newnodetype_uuid + local newnodex=0 newnodey=0 + local BUILTINMODELS="Cloud|VPCS|NAT|Frame Relay switch|Ethernet hub|Ethernet switch" cmd=$1 shift arg="$*" @@ -1846,23 +1906,35 @@ debug "post replacedargs is [$replacedargs]" endpoint=${arg_array[0]} && unset 'arg_array[0]' whattolist=${endpoint} actionname=${arg_array[1]} && unset 'arg_array[1]' + GLOBALACTION="$actionname" if [[ $actionname == "add" ]]; then newname=${arg_array[2]} if [[ -z $newname ]]; then error "Name of new $whattolist not provided." return 1 fi - # ie. look for models named 'IOS' -# oooo ...if we find one, check its template_type -# if it's qemu then use template_id to figure out appliance id??? -# otherwise just use template_type - whattolist="model" - newtype=".*${arg_array[3]}.*" - actionfilter="-f${newtype}" - - + newnodetype="${arg_array[3]}" # eg. VPCS, Cisco IOS, etc +debug "jjjjj newname is $newname" +debug "jjjjj newnodetype is $newnodetype" +debug "jjjjj whattolist is $whattolist" + # is it a builtin appliance? + if [[ $newnodetype =~ ^($BUILTINMODELS)$ ]]; then + debug "adding a gns3 built-in node ($newnodetype)" + addendpoint="node" + #whattolist="" + #newnodetype=$(getnodetypeforadd $newnodetype) + #newnodetype_uuid="" + whattolist="model" + actionfilter="-f.*${newnodetype}.*" + else + debug "adding an appliance ($newnodetype)" + addendpoint="appliance" + # we will lookup the template ID of "nodetype" later... + whattolist="model" + actionfilter="-f.*${newnodetype}.*" + fi else # start/stop/etc if [[ ${#arg_array[@]} -ge 1 ]]; then @@ -1912,6 +1984,9 @@ debug "post replacedargs is [$replacedargs]" q) DONE=1 ;; + la) + listcommandaliases + ;; help) listcommands ADMIN ;; @@ -1937,7 +2012,6 @@ debug "post replacedargs is [$replacedargs]" ;; action) # TODO: ooremove any output format opts - validate_action ${endpoint} $actionname if [[ $? -ne 0 ]]; then error "'$actionname' is not a valid action for ${endpoint}s" @@ -1950,167 +2024,197 @@ debug "post replacedargs is [$replacedargs]" return 1 fi - # Get a list of objects to operate on - # ie. turn regexp into a list of dcs and obnames first - getdata ${whattolist} list $actionfilter $showerroropt -c -s -q >"$TMPFILE" - rv=$? - if [[ $rv -ne 0 ]]; then - error "Query for matching ${whattolist}s failed." - rv=1 - elif [[ ! -e $TMPFILE ]]; then - error "No matching ${whattolist}s found." - rv=1 - elif grep -q "no results" $TMPFILE; then - error "No ${whattolist}s found matching '$obname'." - rv=1 - elif [[ ! -e $TMPFILE ]]; then - error "Results file does not exist." - rv=1 - else - local ndcs nobs data confirm=0 - ok -debug "tmpfile contents: [$(cat $TMPFILE)]" - echo - data=$(cat "$TMPFILE" | egrep -v "^$") + if [[ -n $whattolist ]]; then + # Get a list of objects to operate on + # ie. turn regexp into a list of dcs and obnames first + getdata ${whattolist} list $actionfilter $showerroropt -c -s -q >"$TMPFILE" + rv=$? + if [[ $rv -ne 0 ]]; then + error "Query for matching ${whattolist}s failed." + rv=1 + elif [[ ! -e $TMPFILE ]]; then + error "No matching ${whattolist}s found." + rv=1 + elif grep -q "no results" $TMPFILE; then + error "No ${whattolist}s found matching '$obname'." + rv=1 + elif [[ ! -e $TMPFILE ]]; then + error "Results file does not exist." + rv=1 + else + local ndcs nobs data confirm=0 + ok + debug "tmpfile contents: [$(cat $TMPFILE)]" + echo + data=$(cat "$TMPFILE" | egrep -v "^$") - # how many servers? - ndcs=$( printf %d $(echo "$data" | awk -F, '{ print $1 }' | sort -u | wc -l)) - [[ $ndcs -eq 1 ]] && dc_ess="" || dc_ess="s" - nobs=$( printf %d $(echo "$data" | awk -F, '{ print $2 }' | sort -u | wc -l)) - [[ $nobs -eq 1 ]] && ob_ess="" || ob_ess="s" + # how many servers? + ndcs=$( printf %d $(echo "$data" | awk -F, '{ print $1 }' | sort -u | wc -l)) + [[ $ndcs -eq 1 ]] && dc_ess="" || dc_ess="s" + nobs=$( printf %d $(echo "$data" | awk -F, '{ print $2 }' | sort -u | wc -l)) + [[ $nobs -eq 1 ]] && ob_ess="" || ob_ess="s" - if [[ $actionname == "connect" ]]; then - if [[ $nobs -gt 1 ]]; then - error "Can't run '$actionname' with multiple objects" - return 1 - else - confirm=1 - fi - elif [[ $actionname == "add" ]]; then - local allobs alluuids o_arr ou_arr - allobs=$(echo "$data" | awk -F, '{ print $2 }' | sort -u) - alluuids=$(echo "$data" | awk -F, '{ print $3 }' | sort -u) - o_arr=($allobs) - ou_arr=($alluuids) + if [[ $actionname == "connect" ]]; then + if [[ $nobs -gt 1 ]]; then + error "Can't run '$actionname' with multiple objects" + return 1 + else + confirm=1 + fi + elif [[ $actionname == "add" ]]; then + local allobs alluuids o_arr ou_arr + allobs=$(echo "$data" | awk -F, '{ print $2 }' | sort -u) + alluuids=$(echo "$data" | awk -F, '{ print $3 }' | sort -u) + o_arr=($allobs) + ou_arr=($alluuids) - if [[ $nobs -gt 1 ]]; then - local o n - info "Matched multiple ${whattolist}s:" - newtype="" - while [[ -z $newtype ]]; do - echo - n=1 - while read -r o; do - printf "%3d. %s\n" $n "${o_arr[$n]}" - n=$((n + 1)) - done <<<"$allobs" - echo - getstr ":" "" "Select one (q to abort)" - if [[ -n $retstr ]]; then - if [[ $retstr == "q" ]]; then - break - elif [[ $retstr =~ ^[0-9]*$ ]]; then - if [[ $retstr -le 0 || $retstr -ge $n ]]; then - error "Invalid selection" - else - newtype="${o_arr[$retstr]}" - newtype_uuid="${ou_arr[$retstr]}" - fi - else - local matched=0 x allmatches="" this thisuuid - for x in ${!o_arr[@]}; do - this="${o_arr[$x]}" - thisuuid="${ou_arr[$x]}" - shopt -s nocasematch - if [[ ${this} =~ $retstr ]]; then - newtype="$this" - newtype_uuid="$thisuuid" - allmatches="$allmatches [$this]" - matched=$((matched + 1)) + if [[ $nobs -gt 1 ]]; then + local o n + info "Matched multiple ${whattolist}s:" + newnodetype="" + while [[ -z $newnodetype ]]; do + echo + n=1 + while read -r o; do + printf "%3d. %s\n" $n "${o_arr[$n]}" + n=$((n + 1)) + done <<<"$allobs" + echo + getstr ":" "" "Select one (q to abort)" + if [[ -n $retstr ]]; then + if [[ $retstr == "q" ]]; then + break + elif [[ $retstr =~ ^[0-9]*$ ]]; then + if [[ $retstr -le 0 || $retstr -ge $n ]]; then + error "Invalid selection" + else + newnodetype="${o_arr[$retstr]}" + newnodetype_uuid="${ou_arr[$retstr]}" + fi + else + local matched=0 x allmatches="" this thisuuid + for x in ${!o_arr[@]}; do + this="${o_arr[$x]}" + thisuuid="${ou_arr[$x]}" + shopt -s nocasematch + if [[ ${this} =~ $retstr ]]; then + newnodetype="$this" + newnodetype_uuid="$thisuuid" + allmatches="$allmatches [$this]" + matched=$((matched + 1)) + fi + shopt -u nocasematch + done + if [[ $matched -eq 0 ]]; then + error "'$retstr' doesn't match any choice" + newnodetype="" + elif [[ $matched -gt 1 ]]; then + error "'$retstr' matched multiple choices: $allmatches" + newnodetype="" fi - shopt -u nocasematch - done - if [[ $matched -eq 0 ]]; then - error "'$retstr' doesn't match any choice" - newtype="" - elif [[ $matched -gt 1 ]]; then - error "'$retstr' matched multiple choices: $allmatches" - newtype="" fi fi - fi - done - else - newtype="$allobs" - newtype_uuid="$alluuids" + done + else + newnodetype="$allobs" + newnodetype_uuid="$alluuids" + fi + if [[ -z $newnodetype ]]; then + confirm=0 + else + notify_nodots "Adding a new ${BOLD}$newnodetype${PLAIN}${PURPLE} named $BOLD$newname${PLAIN}" + confirm=1 + fi + else # action is not add/connect + echo -e "${PURPLE}About to run '${BOLD}$actionname${PLAIN}${PURPLE}' on ${BOLD}${nobs}${PLAIN}${PURPLE} ${whattolist}${ob_ess} on ${BOLD}${ndcs}${PLAIN}${PURPLE} server${dc_ess}:${PLAIN}" + echo "$data" | awk -F, "BEGIN {lastdc=\"\"} { if (\$1 != lastdc) { print \" ${YELLOW}- ${BOLD}\" \$1 \"${PLAIN}\"; lastdc=\$1; } print \" ${YELLOW}- \" \$2 \"${PLAIN}\"}" + + echo + if [[ $ndcs -le 1 ]]; then + getyn n "Really proceed" + [[ $? -eq 0 ]] && confirm=1 || confirm=0 + else + local confirmcode entered_string + confirmcode=$(generate_random_string) + notify_nodots "Confirmation code is: ${BOLD}${confirmcode}${PLAIN}" + getstr ":" "n" "Enter the above code to proceed, anything else will abort" + entered_string="$retstr" + [[ $entered_string == $confirmcode ]] && confirm=1 || confirm=0 + fi fi - if [[ -z $newtype ]]; then - confirm=0 + fi # end if data query got results + else + # we dont need to do a data query + newnodetype_uuid="" + confirm=1 + fi + + if [[ $confirm -eq 1 ]]; then + if [[ $actionname == "add" ]]; then + local postdata + # We use alternate values for the actiontarget string here: + # loc=servername (normal) + # ob=name of new ob to add + # obuuid=uuid of model + # extrainfo=curl post data in the form of key1:val1^key2:val2... + + if [[ $addendpoint == "node" ]]; then + local nodetypeforadd + # gns3 wants the nodetype in the post data and in a + # special format. + nodetypeforadd=$(getnodetypeforadd $newnodetype) + postdata="name:$newname^node_type:$nodetypeforadd^compute_id:local^template_id:$newnodetype_uuid" + # ...and NOT in the URL + newnodetype="" + newnodetype_uuid="" + + actiontargets="$curlocs,$newname,$newnodetype_uuid" + elif [[ $addendpoint == "appliance" ]]; then + # name will be autogenerated from the appliance name. + postdata="x:$newnodex^y:$newnodey" + + actiontargets="$curlocs,$newname,$newnodetype_uuid" else - notify_nodots "Adding a new ${BOLD}$newtype${PLAIN}${PURPLE} named $BOLD$newname${PLAIN}" - confirm=1 + error "Don't know how to add node with endpoint of '$endpoint'" + return 1 fi + actiontargets="${actiontargets},$postdata" + + # replace endpoint with the correct one based on whether + # we are adding a gns3 builtin node or an appliance + endpoint="${addendpoint}" else - echo -e "${PURPLE}About to run '${BOLD}$actionname${PLAIN}${PURPLE}' on ${BOLD}${nobs}${PLAIN}${PURPLE} ${whattolist}${ob_ess} on ${BOLD}${ndcs}${PLAIN}${PURPLE} server${dc_ess}:${PLAIN}" - echo "$data" | awk -F, "BEGIN {lastdc=\"\"} { if (\$1 != lastdc) { print \" ${YELLOW}- ${BOLD}\" \$1 \"${PLAIN}\"; lastdc=\$1; } print \" ${YELLOW}- \" \$2 \"${PLAIN}\"}" - - echo - if [[ $ndcs -le 1 ]]; then - getyn n "Really proceed" - [[ $? -eq 0 ]] && confirm=1 || confirm=0 - else - local confirmcode entered_string - confirmcode=$(generate_random_string) - notify_nodots "Confirmation code is: ${BOLD}${confirmcode}${PLAIN}" - getstr ":" "n" "Enter the above code to proceed, anything else will abort" - entered_string="$retstr" - [[ $entered_string == $confirmcode ]] && confirm=1 || confirm=0 - fi + actiontargets=$(echo "$data") fi - - if [[ $confirm -eq 1 ]]; then - if [[ $actionname == "add" ]]; then - # We use alternate values for the actiontarget string here: - # loc=servername (normal) - # ob=name of new ob to add - # obuuid=uuid of model - # extrainfo=curl post data - actiontargets="$curlocs,$newname,$newtype_uuid" -# ooo - #actiontargets="${actiontargets},'{\"name\": \"$newname\", \"node_type\": \"$newtype\", \"compute_id\": \"local\"}'" - actiontargets="${actiontargets},name:$newname^node_type:$newtype^compute_id:local" - else - actiontargets=$(echo "$data") - fi - if [[ $actionname == "connect" ]]; then - local devname sevname srvport - devname=$(echo "$data" | awk -F, '{ print $2 }') - srvname=$(echo "$data" | awk -F, '{ print $1 }') - srvport=$(echo "$data" | awk -F, '{ print $4 }') - notify_nodots "Connecting to $devname ($srvname:$srvport)" - opts+=("-F") - else - notify "Submitting actions to gns API" - fi - rm -f "$TMPFILE" + if [[ $actionname == "connect" ]]; then + local devname sevname srvport + devname=$(echo "$data" | awk -F, '{ print $2 }') + srvname=$(echo "$data" | awk -F, '{ print $1 }') + srvport=$(echo "$data" | awk -F, '{ print $4 }') + notify_nodots "Connecting to $devname ($srvname:$srvport)" + opts+=("-F") + else + notify "Submitting actions to gns API" + fi + rm -f "$TMPFILE" debug "about to call runaction with:" +debug " endpoint = $endpoint" debug " obtype = $endpoint" debug " actionname = $actionname" debug " actiontargets = $actiontargets" debug " opts = ${opts[@]}" debug " outputfile = ${TMPFILE}" - runaction ${endpoint} $actionname "$actiontargets" ${opts[@]} >"$TMPFILE" - rv=$? - if [[ $actionname != "connect" ]]; then - ok - [[ -e $TMPFILE ]] && cat "$TMPFILE" | $pipe - echo - info $(printf "action submission time: %s seconds" "$lastqsecs") - fi + runaction ${endpoint} $actionname "$actiontargets" ${opts[@]} >"$TMPFILE" + rv=$? + if [[ $actionname != "connect" ]]; then + ok + [[ -e $TMPFILE ]] && cat "$TMPFILE" | $pipe + echo + info $(printf "action submission time: %s seconds" "$lastqsecs") fi - fi + fi # end if confirm == 1 rm -f "$TMPFILE" ;; exit) @@ -2161,6 +2265,7 @@ function checkfor() { # checkfor name [pkg_name] local what pkgname local hw os ok=0 confirm=0 local alt="" rv globvar="" + local realpath="" what=$1 pkg_name=${2:-$what} @@ -2169,29 +2274,33 @@ function checkfor() { # checkfor name [pkg_name] if [[ $hw == "aarch64" ]]; then # Android Termux alias which="command -v" fi - which $what >/dev/null 2>&1 + if [[ $what == "gdate" ]]; then + alt=date + globvar=GDATE + elif [[ $what == "gsed" ]]; then + alt=sed + globvar=GSED + fi + realpath=$(which $what 2>&1) rv=$? if [[ $rv -ne 0 ]]; then - if [[ $what == "gdate" ]]; then - alt=date - globvar=GDATE - elif [[ $what == "gsed" ]]; then - alt=sed - globvar=GSED - fi if [[ -n $alt ]]; then $alt --version 2>/dev/null | grep -q GNU 2>/dev/null if [[ $? -eq 0 ]]; then - local path - altpath=$(which $alt 2>/dev/null) - what=${alt} - [[ -n $globvar ]] && eval "$globvar=\"$altpath\"" + realpath=$(which $alt 2>/dev/null) rv=0 fi fi fi if [[ $rv -eq 0 ]]; then + + if [[ -n $globvar ]]; then + debug "found $what at $realpath - have set \$$globvar" + eval "$globvar=\"$realpath\"" + else + debug "found $what at $realpath - no globvar" + fi ok=1 else error "$what binary not found in \$PATH." @@ -2221,7 +2330,9 @@ function checkfor() { # checkfor name [pkg_name] fi fi which $what >/dev/null 2>&1 - return $? + rv=$? + [[ $rv -eq 0 && -n $globvar ]] && eval "$globvar=\"$realpath\"" + return $rv } function killtmux() { @@ -2308,6 +2419,8 @@ LINK="$BLUE$UNDERLINE" UNDERLINE_PRINTED=$(echo -en "$UNDERLINE") UNDERLINE_LENGTH=${#UNDERLINE_PRINTED} +CURLERRORSTRINGS="(^40.:|error|status.*403)" + # Generate sed script to add colours to certain words UUIDCHAR="[0-9a-f]" UUID_REGEXP=${UUIDCHAR}\{8\}-${UUIDCHAR}\{4\}-${UUIDCHAR}\{4\}-${UUIDCHAR}\{4\}-${UUIDCHAR}\{12\} @@ -2339,7 +2452,7 @@ addendpoint nodes projects/_CURPROJECT_/nodes node node_id name addepalias nodes n addeptitles nodes "Node " "Model_UUID" "Status " "Console_Port" addepfields nodes ".name" ".template_id" ".status" ".console" - addepactions nodes start stop connect add + addepactions nodes start stop connect add del addendpoint links projects/_CURPROJECT_/links link link_id link_id addepalias links l @@ -2351,6 +2464,11 @@ addendpoint models templates model template_id name addeptitles models "Name" "Category" "UUID" addepfields models ".name" ".category" ".template_id" +addendpoint appliances appliances appliance template_id name + addepalias appliances a + addeptitles appliances "Name" "Category" "Ports" + addepfields appliances ".name" ".category" ".qemu.adapters" + addcmd list "List elements of a given type (eg. nodes, links, etc)" 1+ ls l addcmdusage list "object_type [regexp_filter]" "object_type can be: [${ep_name[*]}]" @@ -2383,10 +2501,13 @@ addcmdalias "stop" "action node stop" "" addcmdalias "connect" "action node connect" "" addcmdalias "c" "action node connect" "" addcmdalias "add" "action node add" "" +addcmdalias "rm" "action node del" "" +addcmdalias "del" "action node del" "" addcmd help "List regular commands" 0 "?" "h" addcmd exit "Exit from gnscli" 0 quit addcmd -a help "List admin commands" 0 "?" "h" +addcmd -a la "List command aliases" 0 addcmd -a p "Select project filter (comma or space separated list)" 1 loc addcmdusage p "project_list" "project_list is a comma-separated list made up of [${loc_name[*]}]" addcmd -a lp "List GNS3 projects on current server(s)" 0 listprojects