newfeature: can now add a new node, but only builtin types

newfeature: can now delete nodes
This commit is contained in:
Rob Pearce 2021-12-31 16:32:08 +11:00
parent 0f8036657b
commit d618ea2b1a
1 changed files with 304 additions and 183 deletions

487
gnscli.sh
View File

@ -1,9 +1,8 @@
#!/bin/bash #!/bin/bash
# add node # add appliance
# issue with json post data # clean up action output
# rename project # rename project
# delete node
# node stop givesjq error # node stop givesjq error
@ -770,20 +769,31 @@ function runcurlget() { # location api_endpoint(ovname)
return $rv return $rv
} }
function runcurldatapost() { # location api_endpoint "curl data" function runcurldatapost() { # location api_endpoint endpoint_uuid "curl data"
local thisapi thisurl curlres rv local thisapi thisurl curlres rv
local loc api_endpoint obname ovmethod local loc api_endpoint obname ovmethod
local endpoint_uuid
local data="" local data=""
loc="$1" loc="$1"
api_endpoint="$2" api_endpoint="$2"
data="$3" endpoint_uuid="$3"
data="$4"
thisapi=$(get $loc api) thisapi=$(get $loc api)
[[ -z $thisapi ]] && echo "cant find api for '$loc'" && return 1 [[ -z $thisapi ]] && echo "cant find api for '$loc'" && return 1
#thisauthdom=$(get $loc authdomain) #thisauthdom=$(get $loc authdomain)
debug -f "data is $data"
thisurl="$thisapi/$api_endpoint" thisurl="$thisapi/$api_endpoint"
thisurl=${thisurl/\/v2\/appliances/\/v2\/projects\/_CURPROJECT_\/appliances} # special case
thisurl=${thisurl/_CURPROJECT_/$curprojid} 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" debug -f "curl -XPOST -sk --header 'Content-type: application/xml' --header 'Accept: application/json' -d \"$data\" $thisurl"
set -x set -x
@ -800,8 +810,9 @@ set +x
function runcurlaction() { # location api_endpoint(ovname) obname ovmethod ["curl data"] function runcurlaction() { # location api_endpoint(ovname) obname ovmethod ["curl data"]
local thisapi thisurl curlres rv local thisapi thisurl curlres rv
#local thisauthdom u p thisauthstr #local thisauthdom u p thisauthstr
local loc api_endpoint obname ovmethod local loc api_endpoint obname ovmethou
local data="" local data=""
local curlmethod="POST"
#local data="<action/>" #local data="<action/>"
loc="$1" loc="$1"
api_endpoint="$2" api_endpoint="$2"
@ -822,8 +833,15 @@ debug -f "data is $data"
#unset u #unset u
#unset p #unset p
debug -f "curl -XPOST -sk --header 'Content-type: application/xml' --header 'Accept: application/json' -d \"$data\" $thisurl" if [[ $GLOBALACTION == "del" ]]; then
curlres=$(curl -XPOST -sk --header 'Content-type: application/xml' --header 'Accept: application/json' -d "$data" $thisurl) 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=$?
[[ $rv -ne 0 ]] && error "curl to $thisurl failed" [[ $rv -ne 0 ]] && error "curl to $thisurl failed"
@ -876,6 +894,7 @@ function getgnsmethod() {
start) echo "start";; start) echo "start";;
stop) echo "stop";; stop) echo "stop";;
add) echo "";; add) echo "";;
del) echo "";;
#migrate) echo "migrate";; #migrate) echo "migrate";;
*) *)
echo echo
@ -923,8 +942,13 @@ function runaction_loc() { # runaction_loc syd|etc api_endpoint action_name ob_u
opts="$*" opts="$*"
opts_arr=( $opts ) opts_arr=( $opts )
debug -f "extrainfo : $extrainfo" debug -f "arglist - loc: $loc"
debug -f "remaining opts: $opts" 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 if [[ $actionname == "add" ]]; then
curldata=$(makejson "$extrainfo") curldata=$(makejson "$extrainfo")
fi fi
@ -963,21 +987,35 @@ debug -f "remaining opts: $opts"
return 1 return 1
fi fi
debug -f "ABOUT TO CALL CURL FUNCTION...."
debug -f "location: ${loc}" debug -f "location: ${loc}"
debug -f "api endpoint: ${api_endpoint}" debug -f "api endpoint: ${api_endpoint}"
debug -f "jq obj: ${jq_obj}" debug -f "jq obj: ${jq_obj}"
debug -f "actionname: ${actionname} (gns method: '$method')" debug -f "actionname: ${actionname} (gns method: '$method')"
debug -f "obname: ${ob}" debug -f "ob: ${ob}"
debug -f "options: ${opts}" debug -f "options: ${opts}"
debug -f "curldata: ${curldata}" debug -f "curldata: ${curldata}"
if [[ $action == "add" ]]; then 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=$? crv=$?
else else
curlres=$(runcurlaction $loc $api_endpoint $ob $method "$curldata" ) curlres=$(runcurlaction "$loc" "$api_endpoint" "$ob" "$method" "$curldata" )
crv=$? crv=$?
fi 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 if [[ $crv -ne 0 ]]; then
rv=1 rv=1
fi fi
@ -1144,7 +1182,7 @@ function getbasefilter() { # epidx [regexp_filter]
bf="${bf}] ), (.[] | $refilter | [\"_LOCATION_\"" bf="${bf}] ), (.[] | $refilter | [\"_LOCATION_\""
first=1 first=1
for x in ${fields[@]}; do for x in ${fields[@]}; do
thisdefault="defaultvalue" thisdefault="not_found"
[[ $x == ".status" ]] && thisdefault="project_closed" [[ $x == ".status" ]] && thisdefault="project_closed"
x=${x//^/ } x=${x//^/ }
#bf="${bf}, try(${x}) catch(\"xx\")" #bf="${bf}, try(${x}) catch(\"xx\")"
@ -1290,12 +1328,16 @@ debug "opts is $opts"
else else
pids="" pids=""
while read -r line ; do while read -r line ; do
debug -f "processing line: [$line]"
loc=$(echo "$line" | cut -d, -f1) loc=$(echo "$line" | cut -d, -f1)
ob=$(echo "$line" | cut -d, -f2) ob=$(echo "$line" | cut -d, -f2)
obuuid=$(echo "$line" | cut -d, -f3) obuuid=$(echo "$line" | cut -d, -f3)
extrainfo=$(echo "$line" | cut -d, -f4-) extrainfo=$(echo "$line" | cut -d, -f4-)
debug "extrainfo is: $extrainfo" debug -f "--> loc = $loc"
runaction_loc $loc $epidx $actionname $obuuid $ob "$extrainfo" $opts > "$TMPDIR/run,$loc,$ob" & 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 $!" pids="$pids $!"
done <<< "$targetlist" done <<< "$targetlist"
@ -1390,6 +1432,7 @@ function validate_action() { # nodes/vms/etv actionname
local what acion epidx local what acion epidx
what="$1" what="$1"
action="$2" action="$2"
debug "validating action '$action' on obtype '$what'"
epidx=$(getepidx $what) epidx=$(getepidx $what)
[[ $? -ne 0 ]] && return 1 [[ $? -ne 0 ]] && return 1
[[ ${ep_validactions[$epidx]} != *\ $action\ * ]] && return 1 [[ ${ep_validactions[$epidx]} != *\ $action\ * ]] && return 1
@ -1697,6 +1740,14 @@ function listcommands() {
done 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() { function generate_random_string() {
local segmentlen=5 x str="" thissegment local segmentlen=5 x str="" thissegment
@ -1752,11 +1803,20 @@ function expand_cmdalias() { # expand_cmdalias "cmd" newcmd_var newargs_var "ar
return 1 return 1
} }
function getnodetypeforadd() {
local nt
nt=$(echo "$1" | tr 'A-Z' 'a-z' | tr ' ' '_')
echo "$nt"
}
function processcmd() { function processcmd() {
local cmd arg newarg rv newlocs x err admin idx opts pipe gotargs local cmd arg newarg rv newlocs x err admin idx opts pipe gotargs
local whattolist actionname="" actionfilter="" local whattolist actionname="" actionfilter=""
local showerror=0 showerroropt="" 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 cmd=$1
shift shift
arg="$*" arg="$*"
@ -1846,23 +1906,35 @@ debug "post replacedargs is [$replacedargs]"
endpoint=${arg_array[0]} && unset 'arg_array[0]' endpoint=${arg_array[0]} && unset 'arg_array[0]'
whattolist=${endpoint} whattolist=${endpoint}
actionname=${arg_array[1]} && unset 'arg_array[1]' actionname=${arg_array[1]} && unset 'arg_array[1]'
GLOBALACTION="$actionname"
if [[ $actionname == "add" ]]; then if [[ $actionname == "add" ]]; then
newname=${arg_array[2]} newname=${arg_array[2]}
if [[ -z $newname ]]; then if [[ -z $newname ]]; then
error "Name of new $whattolist not provided." error "Name of new $whattolist not provided."
return 1 return 1
fi fi
# ie. look for models named 'IOS' newnodetype="${arg_array[3]}" # eg. VPCS, Cisco IOS, etc
# 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}"
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 else
# start/stop/etc # start/stop/etc
if [[ ${#arg_array[@]} -ge 1 ]]; then if [[ ${#arg_array[@]} -ge 1 ]]; then
@ -1912,6 +1984,9 @@ debug "post replacedargs is [$replacedargs]"
q) q)
DONE=1 DONE=1
;; ;;
la)
listcommandaliases
;;
help) help)
listcommands ADMIN listcommands ADMIN
;; ;;
@ -1937,7 +2012,6 @@ debug "post replacedargs is [$replacedargs]"
;; ;;
action) action)
# TODO: ooremove any output format opts # TODO: ooremove any output format opts
validate_action ${endpoint} $actionname validate_action ${endpoint} $actionname
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
error "'$actionname' is not a valid action for ${endpoint}s" error "'$actionname' is not a valid action for ${endpoint}s"
@ -1950,167 +2024,197 @@ debug "post replacedargs is [$replacedargs]"
return 1 return 1
fi fi
# Get a list of objects to operate on if [[ -n $whattolist ]]; then
# ie. turn regexp into a list of dcs and obnames first # Get a list of objects to operate on
getdata ${whattolist} list $actionfilter $showerroropt -c -s -q >"$TMPFILE" # ie. turn regexp into a list of dcs and obnames first
rv=$? getdata ${whattolist} list $actionfilter $showerroropt -c -s -q >"$TMPFILE"
if [[ $rv -ne 0 ]]; then rv=$?
error "Query for matching ${whattolist}s failed." if [[ $rv -ne 0 ]]; then
rv=1 error "Query for matching ${whattolist}s failed."
elif [[ ! -e $TMPFILE ]]; then rv=1
error "No matching ${whattolist}s found." elif [[ ! -e $TMPFILE ]]; then
rv=1 error "No matching ${whattolist}s found."
elif grep -q "no results" $TMPFILE; then rv=1
error "No ${whattolist}s found matching '$obname'." elif grep -q "no results" $TMPFILE; then
rv=1 error "No ${whattolist}s found matching '$obname'."
elif [[ ! -e $TMPFILE ]]; then rv=1
error "Results file does not exist." elif [[ ! -e $TMPFILE ]]; then
rv=1 error "Results file does not exist."
else rv=1
local ndcs nobs data confirm=0 else
ok local ndcs nobs data confirm=0
debug "tmpfile contents: [$(cat $TMPFILE)]" ok
echo debug "tmpfile contents: [$(cat $TMPFILE)]"
data=$(cat "$TMPFILE" | egrep -v "^$") echo
data=$(cat "$TMPFILE" | egrep -v "^$")
# how many servers? # how many servers?
ndcs=$( printf %d $(echo "$data" | awk -F, '{ print $1 }' | sort -u | wc -l)) ndcs=$( printf %d $(echo "$data" | awk -F, '{ print $1 }' | sort -u | wc -l))
[[ $ndcs -eq 1 ]] && dc_ess="" || dc_ess="s" [[ $ndcs -eq 1 ]] && dc_ess="" || dc_ess="s"
nobs=$( printf %d $(echo "$data" | awk -F, '{ print $2 }' | sort -u | wc -l)) nobs=$( printf %d $(echo "$data" | awk -F, '{ print $2 }' | sort -u | wc -l))
[[ $nobs -eq 1 ]] && ob_ess="" || ob_ess="s" [[ $nobs -eq 1 ]] && ob_ess="" || ob_ess="s"
if [[ $actionname == "connect" ]]; then if [[ $actionname == "connect" ]]; then
if [[ $nobs -gt 1 ]]; then if [[ $nobs -gt 1 ]]; then
error "Can't run '$actionname' with multiple objects" error "Can't run '$actionname' with multiple objects"
return 1 return 1
else else
confirm=1 confirm=1
fi fi
elif [[ $actionname == "add" ]]; then elif [[ $actionname == "add" ]]; then
local allobs alluuids o_arr ou_arr local allobs alluuids o_arr ou_arr
allobs=$(echo "$data" | awk -F, '{ print $2 }' | sort -u) allobs=$(echo "$data" | awk -F, '{ print $2 }' | sort -u)
alluuids=$(echo "$data" | awk -F, '{ print $3 }' | sort -u) alluuids=$(echo "$data" | awk -F, '{ print $3 }' | sort -u)
o_arr=($allobs) o_arr=($allobs)
ou_arr=($alluuids) ou_arr=($alluuids)
if [[ $nobs -gt 1 ]]; then if [[ $nobs -gt 1 ]]; then
local o n local o n
info "Matched multiple ${whattolist}s:" info "Matched multiple ${whattolist}s:"
newtype="" newnodetype=""
while [[ -z $newtype ]]; do while [[ -z $newnodetype ]]; do
echo echo
n=1 n=1
while read -r o; do while read -r o; do
printf "%3d. %s\n" $n "${o_arr[$n]}" printf "%3d. %s\n" $n "${o_arr[$n]}"
n=$((n + 1)) n=$((n + 1))
done <<<"$allobs" done <<<"$allobs"
echo echo
getstr ":" "" "Select one (q to abort)" getstr ":" "" "Select one (q to abort)"
if [[ -n $retstr ]]; then if [[ -n $retstr ]]; then
if [[ $retstr == "q" ]]; then if [[ $retstr == "q" ]]; then
break break
elif [[ $retstr =~ ^[0-9]*$ ]]; then elif [[ $retstr =~ ^[0-9]*$ ]]; then
if [[ $retstr -le 0 || $retstr -ge $n ]]; then if [[ $retstr -le 0 || $retstr -ge $n ]]; then
error "Invalid selection" error "Invalid selection"
else else
newtype="${o_arr[$retstr]}" newnodetype="${o_arr[$retstr]}"
newtype_uuid="${ou_arr[$retstr]}" newnodetype_uuid="${ou_arr[$retstr]}"
fi fi
else else
local matched=0 x allmatches="" this thisuuid local matched=0 x allmatches="" this thisuuid
for x in ${!o_arr[@]}; do for x in ${!o_arr[@]}; do
this="${o_arr[$x]}" this="${o_arr[$x]}"
thisuuid="${ou_arr[$x]}" thisuuid="${ou_arr[$x]}"
shopt -s nocasematch shopt -s nocasematch
if [[ ${this} =~ $retstr ]]; then if [[ ${this} =~ $retstr ]]; then
newtype="$this" newnodetype="$this"
newtype_uuid="$thisuuid" newnodetype_uuid="$thisuuid"
allmatches="$allmatches [$this]" allmatches="$allmatches [$this]"
matched=$((matched + 1)) 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 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 fi
fi
done done
else else
newtype="$allobs" newnodetype="$allobs"
newtype_uuid="$alluuids" 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 fi
if [[ -z $newtype ]]; then fi # end if data query got results
confirm=0 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 else
notify_nodots "Adding a new ${BOLD}$newtype${PLAIN}${PURPLE} named $BOLD$newname${PLAIN}" error "Don't know how to add node with endpoint of '$endpoint'"
confirm=1 return 1
fi 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 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}" actiontargets=$(echo "$data")
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 fi
if [[ $actionname == "connect" ]]; then
if [[ $confirm -eq 1 ]]; then local devname sevname srvport
if [[ $actionname == "add" ]]; then devname=$(echo "$data" | awk -F, '{ print $2 }')
# We use alternate values for the actiontarget string here: srvname=$(echo "$data" | awk -F, '{ print $1 }')
# loc=servername (normal) srvport=$(echo "$data" | awk -F, '{ print $4 }')
# ob=name of new ob to add notify_nodots "Connecting to $devname ($srvname:$srvport)"
# obuuid=uuid of model opts+=("-F")
# extrainfo=curl post data else
actiontargets="$curlocs,$newname,$newtype_uuid" notify "Submitting actions to gns API"
# ooo fi
#actiontargets="${actiontargets},'{\"name\": \"$newname\", \"node_type\": \"$newtype\", \"compute_id\": \"local\"}'" rm -f "$TMPFILE"
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"
debug "about to call runaction with:" debug "about to call runaction with:"
debug " endpoint = $endpoint"
debug " obtype = $endpoint" debug " obtype = $endpoint"
debug " actionname = $actionname" debug " actionname = $actionname"
debug " actiontargets = $actiontargets" debug " actiontargets = $actiontargets"
debug " opts = ${opts[@]}" debug " opts = ${opts[@]}"
debug " outputfile = ${TMPFILE}" debug " outputfile = ${TMPFILE}"
runaction ${endpoint} $actionname "$actiontargets" ${opts[@]} >"$TMPFILE" runaction ${endpoint} $actionname "$actiontargets" ${opts[@]} >"$TMPFILE"
rv=$? rv=$?
if [[ $actionname != "connect" ]]; then if [[ $actionname != "connect" ]]; then
ok ok
[[ -e $TMPFILE ]] && cat "$TMPFILE" | $pipe [[ -e $TMPFILE ]] && cat "$TMPFILE" | $pipe
echo echo
info $(printf "action submission time: %s seconds" "$lastqsecs") info $(printf "action submission time: %s seconds" "$lastqsecs")
fi
fi fi
fi fi # end if confirm == 1
rm -f "$TMPFILE" rm -f "$TMPFILE"
;; ;;
exit) exit)
@ -2161,6 +2265,7 @@ function checkfor() { # checkfor name [pkg_name]
local what pkgname local what pkgname
local hw os ok=0 confirm=0 local hw os ok=0 confirm=0
local alt="" rv globvar="" local alt="" rv globvar=""
local realpath=""
what=$1 what=$1
pkg_name=${2:-$what} pkg_name=${2:-$what}
@ -2169,29 +2274,33 @@ function checkfor() { # checkfor name [pkg_name]
if [[ $hw == "aarch64" ]]; then # Android Termux if [[ $hw == "aarch64" ]]; then # Android Termux
alias which="command -v" alias which="command -v"
fi 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=$? rv=$?
if [[ $rv -ne 0 ]]; then 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 if [[ -n $alt ]]; then
$alt --version 2>/dev/null | grep -q GNU 2>/dev/null $alt --version 2>/dev/null | grep -q GNU 2>/dev/null
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
local path realpath=$(which $alt 2>/dev/null)
altpath=$(which $alt 2>/dev/null)
what=${alt}
[[ -n $globvar ]] && eval "$globvar=\"$altpath\""
rv=0 rv=0
fi fi
fi fi
fi fi
if [[ $rv -eq 0 ]]; then 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 ok=1
else else
error "$what binary not found in \$PATH." error "$what binary not found in \$PATH."
@ -2221,7 +2330,9 @@ function checkfor() { # checkfor name [pkg_name]
fi fi
fi fi
which $what >/dev/null 2>&1 which $what >/dev/null 2>&1
return $? rv=$?
[[ $rv -eq 0 && -n $globvar ]] && eval "$globvar=\"$realpath\""
return $rv
} }
function killtmux() { function killtmux() {
@ -2308,6 +2419,8 @@ LINK="$BLUE$UNDERLINE"
UNDERLINE_PRINTED=$(echo -en "$UNDERLINE") UNDERLINE_PRINTED=$(echo -en "$UNDERLINE")
UNDERLINE_LENGTH=${#UNDERLINE_PRINTED} UNDERLINE_LENGTH=${#UNDERLINE_PRINTED}
CURLERRORSTRINGS="(^40.:|error|status.*403)"
# Generate sed script to add colours to certain words # Generate sed script to add colours to certain words
UUIDCHAR="[0-9a-f]" UUIDCHAR="[0-9a-f]"
UUID_REGEXP=${UUIDCHAR}\{8\}-${UUIDCHAR}\{4\}-${UUIDCHAR}\{4\}-${UUIDCHAR}\{4\}-${UUIDCHAR}\{12\} 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 addepalias nodes n
addeptitles nodes "Node " "Model_UUID" "Status " "Console_Port" addeptitles nodes "Node " "Model_UUID" "Status " "Console_Port"
addepfields nodes ".name" ".template_id" ".status" ".console" 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 addendpoint links projects/_CURPROJECT_/links link link_id link_id
addepalias links l addepalias links l
@ -2351,6 +2464,11 @@ addendpoint models templates model template_id name
addeptitles models "Name" "Category" "UUID" addeptitles models "Name" "Category" "UUID"
addepfields models ".name" ".category" ".template_id" 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 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[*]}]" 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 "connect" "action node connect" ""
addcmdalias "c" "action node connect" "" addcmdalias "c" "action node connect" ""
addcmdalias "add" "action node add" "" addcmdalias "add" "action node add" ""
addcmdalias "rm" "action node del" ""
addcmdalias "del" "action node del" ""
addcmd help "List regular commands" 0 "?" "h" addcmd help "List regular commands" 0 "?" "h"
addcmd exit "Exit from gnscli" 0 quit addcmd exit "Exit from gnscli" 0 quit
addcmd -a help "List admin commands" 0 "?" "h" 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 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[*]}]" 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 addcmd -a lp "List GNS3 projects on current server(s)" 0 listprojects