Clean up getdata and json filtering code

Can now add/remove links
This commit is contained in:
Rob Pearce 2022-01-02 20:58:57 +11:00
parent dc49f26251
commit bb4d15e508
1 changed files with 391 additions and 223 deletions

492
gnscli.sh
View File

@ -1,5 +1,6 @@
#!/bin/bash
# addepactionusage "links" "add" "ahost aport zhost zport'
# better cinfirmation when removing a link
# clean up action output
# add node issue with menu when type isnt specified
@ -314,7 +315,6 @@ function debug() {
if [[ $VERBOSE -eq 1 ]]; then
if [[ $force -eq 1 ]]; then
echo -e "${PURPLE}${BOLD}${FUNCNAME[1]}(): ${PLAIN}${PURPLE}$*${PLAIN}" >/dev/stderr
echo -e "${PURPLE}${BOLD}${FUNCNAME[1]}(): ${PLAIN}${PURPLE}$*${PLAIN}" >/tmp/a
else
echo -e "${PURPLE}${BOLD}${FUNCNAME[1]}(): ${PLAIN}${PURPLE}$*${PLAIN}" 1>&2
fi
@ -965,8 +965,14 @@ debug -f "arglist - obname: $obname"
debug -f "arglist - extrainfo : $extrainfo"
debug -f "arglist: remaining opts: $opts"
if [[ $actionname == "add" || $actionname == "mv" ]]; then
if [[ -n $RAWJSONPOSTDATA ]]; then
curldata="${RAWJSONPOSTDATA}"
else
curldata=$(makejson "$extrainfo")
fi
fi
RAWJSONPOSTDATA=""
# special case
if [[ $actionname == "connect" ]]; then
@ -1012,7 +1018,9 @@ debug -f "arglist: remaining opts: $opts"
debug -f "curldata: ${curldata}"
if [[ $action == "add" || $action == "mv" ]]; then
# note: "obuuid" is empty when adding a builtin node like VPCS
# note: "obuuid" is empty in some cases, eg:
# adding a builtin node like VPCS
# adding a link
curlres=$(runcurldatapost "$loc" "$api_endpoint" "$obuuid" "$curldata" )
crv=$?
else
@ -1040,6 +1048,55 @@ debug -f "arglist: remaining opts: $opts"
return $rv
}
# uses globals jqscrjpt, jqfilter, awkscript
function apply_filters() { # retvar wantquotes [f][s][a]
local retvar which data wantquotes rawopt qstr
retvar="$1"
wantquotes="${2:-0}"
debug "wantquotes is $wantquotes"
if [[ $wantquotes -eq 0 ]]; then
rawopt="-r"
qstr="without quotes (jq -r)"
elif [[ $wantquotes -eq -1 ]]; then
rawopt="-r"
qstr="REALLY without quotes (jq -r | sed_remove_quotes)"
else
rawopt=""
qstr="with quotes"
fi
[[ -z $retvar ]] && return 1
which="${3:-sfa}"
eval "data=\"\$$retvar\""
debug "applying: $which $qstr"
debug " wantquotes is $wantquotes"
debug " jqfilter is $jqfilter"
debug " jqscript is $jqscript"
debug " awkscript is $awkscript"
if [[ $which == *f* && -n $jqfilter ]]; then
#debug "$retvar pre jqfilter is $data"
echo "$data" >/tmp/a
data=$(echo "$data" | jq $rawopt "$jqfilter" 2>/dev/null)
if [[ $wantquotes -eq -1 ]]; then
data=$(echo "$data" | tr -d '"')
fi
#debug "$retvar post jqfilter is $data"
fi
if [[ $which == *s* && -n $jqscript ]]; then
debug "jqscript contents: $(cat $jqscript)"
debug "$retvar pre jqscript is $data"
data=$(echo "$data" | jq $rawopt -f "$jqscript")
debug "$retvar post jqscript is $data"
fi
if [[ $which == *a* && -n $awkscript ]]; then
debug "$retvar pre awkscript is $data"
data=$(echo "$data" | awk -f "$awkscript")
fi
eval $retvar=\"\$data\"
return 0
}
function getdata_loc() { # getdata_loc syd|etc api_endpoint [options]
local thisgrid thisauthdom thisurl thisauthstr curlres loc u p
local api_endpoint jq_obj opts opts_arr deffield epidx r1 r2 rv
@ -1065,55 +1122,20 @@ debug "options: ${opts}"
debug "outmode is $outmode"
debug "jqscript is $jqscript"
debug "jqfilter is $jqfilter"
debug "awkscript is $awkscript"
if [[ $outmode == "raw" ]]; then
[[ ! -z $curlres ]] && echo "$curlres" || rv=2
elif [[ $outmode == "verbose" ]]; then
#if [[ $locnum -eq 1 ]]; then
# # bold+underline the heading, and store in a temp file
# echo "$curlres" | jq -r "$jqfilter" 2>/dev/null | tr -d '"' | awk '{ if (NR == 1) { printf "\033[1m\033[4m" $0 "\033[0m\n" } }' >$HEADINGFILE
#fi
r1="$curlres"
if [[ ! -z $jqfilter ]]; then
debug "jqfilter is $jqfilter"
debug "r1 pre jqfilter is $r1"
r1=$(echo "$r1" | jq -r "$jqfilter" 2>/dev/null | tr -d '"')
debug "r1 post jqfilter is $r1"
fi
#if [[ ! -z $regexpfilter ]]; then
# [[ $VERBOSE -eq 1 ]] && debug "r1 pre regexpfilter is $r1"
# r1=$(echo "$r1" | awk -v filter="$regexpfilter" '(NR==1){ print } (NR !=1 && (match($0,filter))) { print }')
#fi
if [[ ! -z $jqscript ]]; then
debug "jqscript is $jqscript"
debug "jqscript contents: $(cat $jqscript)"
debug "r1 pre jqscript is $r1"
echo "$r1" >/tmp/out
r1=$(echo "$r1" | jq -rf "$jqscript")
fi
[[ ! -z $r1 ]] && echo "$r1" || rv=2
# only apply jqfilter
apply_filters r1 $QUOTES f
[[ -n $r1 ]] && echo "$r1" || rv=2
elif [[ $outmode == "verbose" ]]; then
r1="$curlres"
apply_filters r1 $REALLYNOQUOTES
[[ -n $r1 ]] && echo "$r1" || rv=2
else # namesonly
r1=$(echo "$curlres")
if [[ ! -z $jqfilter ]]; then
debug "jqfilter is $jqfilter"
debug "r1 pre jqfilter is $r1"
r1=$(echo "$r1" | jq -r "$jqfilter" 2>/dev/null)
debug "r1 post jqfilter is $r1"
fi
if [[ ! -z $jqscript ]]; then
debug "jqscript is $jqscript"
debug "r1 pre jqscript is $r1"
r1=$(echo "$r1" | jq -rf "$jqscript")
fi
# if [[ ! -z $regexpfilter ]]; then
# debug "r1 pre regexpfilter is $r1"
# r1=$(echo "$r1" | awk -v filter="$regexpfilter" '(NR==1){ print } (NR !=1 && (match($0,filter))) { print }')
# fi
if [[ ! -z $awkscript ]]; then
debug "r1 pre awkscript is $r1"
r1=$(echo "$r1" | awk -f "$awkscript")
fi
apply_filters r1
debug "semi-final r1 is [$r1]"
if [[ $cmd == "list" ]]; then
debug "Global cmd is $GLOBALCMD"
@ -1121,10 +1143,8 @@ echo "$r1" >/tmp/out
# ie. we end up with each line being:
# location,object,object_uuid
#r1=$(echo "$r1" | egrep -v "^$" | sed "s/^/$loc,$thisgrid,/")
r1=$(echo "$r1" | egrep -v "^$" | sed "s/^/$loc,/")
else
#r1=$(echo "$r1" | egrep -v "^$" | sed "s/^/$(echo -e "$BOLD")\[$thisgrid\] $(echo -e "$PLAIN")/")
r1=$(echo "$r1" | egrep -v "^$")
fi
fi
@ -1132,7 +1152,6 @@ echo "$r1" >/tmp/out
[[ -n $r1 ]] && echo "$r1" | sed 's/__END__://' || rv=2
fi
#echo "$curlres" | jq -r "$jqfilter" | sed "s/^/$(echo -e "$BOLD")\[$thisgrid\] $(echo -e "$PLAIN")/"
debug "about to exit with code $rv"
return $rv
}
@ -1195,7 +1214,7 @@ function getbasefilter() { # epidx [regexp_filter]
filterarg="$*"
[[ $filterarg == "*" ]] && filterarg=".*"
[[ -n "$*" ]] && refilter="select(.name|test(\"^$*$\"))" || refilter="."
[[ -n "$*" ]] && refilter="select(.${ep_defaultfield[$epidx]}|test(\"^$*$\"))" || refilter="."
IFS='#' read -r -a titles <<< "${ep_titles[$epidx]}"
IFS='#' read -r -a fields <<< "${ep_fields[$epidx]}"
@ -1293,7 +1312,7 @@ debug "repl is $repl"
debug "table after repl [\n$table]"
# ooo re-render table since field lengths may have changed
# re-render table since field lengths may have changed
table=$(flatten_table "$table")
debug "table in csv is: [$table]"
@ -1388,6 +1407,7 @@ function runaction() { # runaction <nodes|vms|etc> <actionname> targetlist optio
local actionname line all
local force=0 foreground=0 f rv files n thisfile jqres goterror
local good allgoodresults errs allbadresults
# oooo change this
local jqf='[ "_DC_", .job.id, "_OB_", .status ] | @csv'
local jqf_bad='[ "_DC_", "_OB_", .fault.detail, .fault.reason, .status ] | @csv'
local objecttype extrainfo
@ -1464,6 +1484,8 @@ debug -f "--> extrainfo = $extrainfo"
# Capitalise first letter
objecttype=$(echo ${what:0:1} | tr '[a-z]' '[A-Z]')${what:1}
# oooo
# change this jq based on thr action
allgoodresults="Server,${objecttype},Job Status"
allbadresults=""
for f in ${!files[@]} ; do
@ -1599,14 +1621,16 @@ function getdata() { # getdata <nodes|vms|etc> <cmd> options
arraycontains opts_a "-n" && usecache=0 || usecache=1
arraycontains opts_a "-e" && errordebug=1
debug "cmd is $cmd"
debug "opts is $opts"
outfile=$(getarrayopt opts_a o)
refilter=$(getarrayopt opts_a f)
# Allow standard globs rather than regexp globs
[[ $refilter == "*" ]] && refilter=".*"
if [[ -n $refilter ]]; then
obfilter="select(.name|test(\"^$refilter$\""
obfilter="select(.${ep_defaultfield[$epidx]}|test(\"^$refilter$\""
if [[ $ignorecase -eq 1 ]]; then
obfilter="${obfilter}; \"i\"))"
else
@ -1617,8 +1641,8 @@ debug "opts is $opts"
fi
[[ -n $refilter ]] && [[ $quiet -eq 0 ]] && info "${what} filter: ^$refilter$"
# Allow standard globs rather than regexp globs
debug "refilter is $refilter"
debug "obfilter is $obfilter"
# determine jq filter based on object name
jqfilter=""
@ -1645,6 +1669,8 @@ debug "(list) basefilter is $basefilter"
basefilter="${basefilter} + \",\" + (.console|tostring)"
fi
fi
elif [[ $outmode == "raw" ]]; then
[[ $obfilter != "." ]] && basefilter=".[] | $obfilter"
fi
elif [[ $cmd == "net" ]]; then
jqscript="$SCRIPTDIR/diagram.jq"
@ -1653,6 +1679,8 @@ debug "(list) basefilter is $basefilter"
if [[ $outmode == "verbose" ]]; then
error "Verbose mode not supported for show command yet"
return 1
elif [[ $outmode == "raw" ]]; then
error "Raw mode not supported for show command yet - try 'list' instead"
else # namesonly
#basefilter=".$jq_obj[] | select(.name|test(\"${arg_array[1]}\"))"
basefilter=".[] | $obfilter"
@ -1687,7 +1715,11 @@ debug "awkscript is $awkscript"
done
wait $pids
debug all pids finished
if [[ $outmode == "raw" ]]; then
all=$(cat "$TMPDIR"/get.* 2>/dev/null)
else
all=$(cat "$TMPDIR"/get.* 2>/dev/null | tr -d : | egrep -v 'DC|Server' | sed '/^[[:space:]]*$/d')
fi
if [[ -z $all ]]; then
fail
cat "$TMPDIR"/err.*
@ -1702,7 +1734,7 @@ debug all pids finished
cat "$TMPDIR"/err.* >/dev/stderr
fi
fi
debug "combined results: [$all]"
#debug "combined results: [$all]"
end=$(($($GDATE +%s%N)/1000))
lastqsecs=$(echo "scale=2; ($end - $start) / 1000000;" | bc)
@ -1956,12 +1988,148 @@ function getnodetypeforadd() {
}
# populates globals:
# ndcs
# nobs
# dc_ess
# ob_ess
# data
# allobs
# alluids
# o_arr
# ou_arr
function validate_action_obs() { # whattolist actionfilter showerroropt multiple_obs_allowed [retvar_selobname] [retvar_selobuuid]
local whattolist actionfilter showerroropt
local selobname="" selobuuid=""
local retvar_obname retvar_obuuid multiallowed
whattolist="$1"
actionfilter="$2"
showerroropt="$3"
multiallowed="$4"
retvar_obname="$5"
retvar_obuuid="$6"
debug "whattolist=$whattolist"
debug "actionfilter=$actionfilter"
debug "showerroropt=$showerroropt"
debug "multiallowed=$multiallowed"
debug "retvar_obname=$retvar_obname"
debug "retvar_obuuid=$retvar_obuuid"
getdata ${whattolist} list "-f${actionfilter}.*" $showerroropt -c -s -q >"$TMPFILE"
rv=$?
debug "actionfilter=$actionfilter"
if [[ $rv -ne 0 ]]; then
error "Can't find any ${whattolist}s matching '${BOLD}$actionfilter'$PLAIN$RED."
elif [[ ! -e $TMPFILE ]]; then
error "No matching ${whattolist}s found."
elif grep -q "no results" $TMPFILE; then
error "No ${whattolist}s found matching '$obname'."
elif [[ ! -e $TMPFILE ]]; then
error "Results file does not exist."
else
ok
data=$(cat "$TMPFILE" | egrep -v "^$")
ndcs=$( printf %d $(echo "$data" | awk -F, '{ print $1 }' | sort -u | wc -l))
nobs=$( printf %d $(echo "$data" | awk -F, '{ print $2 }' | sort -u | wc -l))
[[ $ndcs -eq 1 ]] && dc_ess="" || dc_ess="s"
[[ $nobs -eq 1 ]] && ob_ess="" || ob_ess="s"
allobs=$(echo "$data" | awk -F, '{ print $2 }' | sort -u)
alluuids=$(echo "$data" | awk -F, '{ print $3 }' | sort -u)
debug "allobs is $allobs"
debug "alluuids is $alluuids"
o_arr=($allobs)
ou_arr=($alluuids)
if [[ $nobs -gt 1 && $multiallowed -eq 0 ]]; then
debug "actionfilter=$actionfilter"
notify_nodots "'${BOLD}${actionfilter}${PLAIN}${PURPLE}' matched multiple ${whattolist}s"
narrowdown "$whattolist" "$allobs" "$alluuids" selobname selobuuid || rv=1
else
selobname="$allobs"
selobuuid="$alluuids"
fi
fi
[[ -n $retvar_obname ]] && eval "$retvar_obname=\"$selobname\""
[[ -n $retvar_obuuid ]] && eval "$retvar_obuuid=\"$selobuuid\""
rm -f "$TMPFILE"
return $rv
}
function narrowdown() { # whattolist "allobs" "all_uuids" retvar_newnodetype retvar_newnodetype_uuid
local whattolist allobs o_arr alluuids ou_arr
local o n rv=0
local newnodetype="" newnodetype_uuid=""
local retvar_newnodetype retvar_newnodetype_uuid
whattolist="$1"
allobs="$2"
alluuids="$3"
retvar_newnodetype="$4"
retvar_newnodetype_uuid="$5"
o_arr=($allobs)
ou_arr=($alluuids)
while [[ -z $newnodetype ]]; do
echo
n=1
while read -r o; do
printf "%3d. %s\n" $n "$o"
n=$((n + 1))
done <<<"$allobs"
echo
getstr ":" "" "Select one (q to abort)"
if [[ -n $retstr ]]; then
if [[ $retstr == "q" ]]; then
rv=1
break
elif [[ $retstr =~ ^[0-9]*$ ]]; then
if [[ $retstr -le 0 || $retstr -ge $n ]]; then
error "Invalid selection"
else
newnodetype="${o_arr[$((retstr - 1))]}"
newnodetype_uuid="${ou_arr[$((retstr - 1))]}"
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
fi
fi
done
eval "$retvar_newnodetype=\"$newnodetype\""
eval "$retvar_newnodetype_uuid=\"$newnodetype_uuid\""
return $rv
}
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 origendpoint builtin newname newnodetype newnodetype_uuid
local epidx endpoint origendpoint builtin newname
local newnodex=0 newnodey=0
local dev devuuid port portnum adapnum
local BUILTINMODELS="Cloud|VPCS|NAT|Frame Relay switch|Ethernet hub|Ethernet switch"
local oldname olduuid
cmd=$1
@ -2063,19 +2231,13 @@ debug "post replacedargs is [$replacedargs]"
error "Name of new $whattolist not provided."
return 1
fi
if [[ $endpoint == "node" ]]; then
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)"
builtin=1
#whattolist=""
#newnodetype=$(getnodetypeforadd $newnodetype)
#newnodetype_uuid=""
whattolist="model"
actionfilter="-f.*${newnodetype}.*"
else
@ -2085,6 +2247,23 @@ debug "jjjjj whattolist is $whattolist"
whattolist="model"
actionfilter="-f.*${newnodetype}.*"
fi
elif [[ $endpoint == "link" ]]; then
local x idx failed=0
idx=2
for x in 0 1; do
dev[$x]=${arg_array[$idx]}; idx=$((idx + 1))
port[$x]=${arg_array[$idx]}; idx=$((idx + 1))
# replace * with .*
port[$x]=$(echo "${port[$x]}" | sed 's#[^\.]\*#\.\*#g')
if [[ -z ${dev[$x]} || -z ${port[$x]} ]]; then
failed=1
fi
done
if [[ $failed -eq 1 ]]; then
error "usage: action link add adev aport zdev zport"
return 1
fi
fi
elif [[ $actionname == "mv" ]]; then
oldname=${arg_array[2]}
newname=${arg_array[3]}
@ -2179,36 +2358,12 @@ debug "jjjjj whattolist is $whattolist"
fi
if [[ -n $whattolist ]]; then
local ndcs nobs data confirm=0
# 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"
if [[ $actionname == "connect" || $actionname == "mv" ]]; then
validate_action_obs ${whattolist} "$actionfilter" "$showerroropt" $NOMULTI || return $?
if [[ $nobs -gt 1 ]]; then
local allobs=$(echo "$data" | awk -F, '{ print $2 }' | sort -u | tr '\n' ',')
error "Can't run '$actionname' with multiple objects (matched: ${allobs%,})"
@ -2217,71 +2372,59 @@ debug "jjjjj whattolist is $whattolist"
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:"
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
fi
fi
done
else
newnodetype="$allobs"
newnodetype_uuid="$alluuids"
fi
if [[ $endpoint == "node" ]]; then
validate_action_obs ${whattolist} "$actionfilter" "$showerroropt" $NOMULTI newnodetype newnodetype_uuid
if [[ -z $newnodetype ]]; then
confirm=0
else
debug "newnodetype is $newnodetype"
debug "newnodeuuid is $newnodetype_uuid"
notify_nodots "Adding a new ${BOLD}$newnodetype${PLAIN}${PURPLE} named $BOLD$newname${PLAIN}"
confirm=1
fi
elif [[ $endpoint == "link" ]]; then
local x json adaplist portnumlist portlist nports newn newu jqs
local jqs_name jqs_num
for x in 0 1; do
local letter portlower
[[ $x -eq 0 ]] && letter=A || letter=Z
debug "about to validate link $x"
validate_action_obs "node" "${dev[$x]}" "$showerroropt" $NOMULTI newn newu || return $?
dev[$x]="$newn"
devuuid[$x]="$newu"
debug "${letter}-node ${dev[$x]} is OK (${dev[$x]})"
debug "getting node $x ports"
json=$(getdata nodes list -q -e -r "-f${dev[$x]}")
portlower=$(echo ${port[$x]} | tr 'A-Z' 'a-z')
jqs=".ports[] | select(.name|ascii_downcase|test(\".*${portlower}.*\"))"
jqs_name="${jqs} | .short_name"
jqs_num="${jqs} | .port_number"
jqs_adapnum="${jqs} | .adapter_number"
portlist=$(echo "$json" | jq -r "$jqs_name")
portnumlist=$(echo "$json" | jq -r "$jqs_num")
adapnumlist=$(echo "$json" | jq -r "$jqs_adapnum")
debug "portlist is $portlist"
debug "portnumlist is $portnumlist"
debug "adapnumlist is $adapnumlist"
#debug "raw port data is\n$json"
nports=$(wc -l <<< "$portlist" | bc)
if [[ -z $portlist || $nports -eq 0 ]]; then
error "${letter}-node ${BOLD}${dev[$x]}$PLAIN$RED has no ports matching '${BOLD}${port[$x]}$PLAIN$RED'."
elif [[ $nports -gt 1 ]]; then
error "${letter}-node ${BOLD}${dev[$x]}$PLAIN$RED has multiple ports matching '${BOLD}${port[$x]}$PLAIN$RED':"
echo -e "${RED}$portlist${PLAIN}" | sed -e 's/^/ /'
else
port[$x]="$portlist"
portnum[$x]="$portnumlist"
adapnum[$x]="$adapnumlist"
debug "${letter}-node ${dev[$x]} port ${port[$x]} is OK (${dev[$x]})"
fi
done
notify_nodots "Adding a link from ${BOLD}${dev[0]} ${port[0]}${PLAIN}${PURPLE} to ${BOLD}${dev[1]} ${port[1]}${PLAIN}"
confirm=1
fi
else # action is not add/connect
validate_action_obs ${whattolist} "$actionfilter" "$showerroropt" $MULTI || return $?
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}\"}"
@ -2298,7 +2441,6 @@ debug "jjjjj whattolist is $whattolist"
[[ $entered_string == $confirmcode ]] && confirm=1 || confirm=0
fi
fi
fi # end if data query got results
else
# we dont need to do a data query
newnodetype_uuid=""
@ -2308,6 +2450,7 @@ debug "jjjjj whattolist is $whattolist"
if [[ $confirm -eq 1 ]]; then
if [[ $actionname == "add" ]]; then
local postdata
if [[ $endpoint == "node" ]]; then
# We use alternate values for the actiontarget string here:
# loc=servername (normal)
# ob=name of new ob to add
@ -2330,8 +2473,22 @@ debug "jjjjj whattolist is $whattolist"
postdata="x:$newnodex^y:$newnodey"
endpoint="model"
fi
actiontargets="$curlocs,$newname,$newnodetype_uuid"
actiontargets="${actiontargets},$postdata"
actiontargets="$curlocs,$newname,$newnodetype_uuid,$postdata"
#actiontargets="${actiontargets},$postdata"
elif [[ $endpoint == "link" ]]; then
#POST 'http://localhost:3080/v2/projects/bfb83f16-dab4-445a-a572-d7cc1801222e/links' -d '{"nodes": [{"adapter_number": 0, "label": {"text": "Text", "x": 42, "y": 0}, "node_id": "d3601934-e39a-4865-9cf5-3e46e1fe24e2", "port_number": 3}, {"adapter_number": 0, "node_id": "d3601934-e39a-4865-9cf5-3e46e1fe24e2", "port_number": 4}]}'
RAWJSONPOSTDATA="{\"nodes\": ["
for n in 0 1; do
RAWJSONPOSTDATA="${RAWJSONPOSTDATA}{\"node_id\": \"${devuuid[$n]}\", \"adapter_number\": ${adapnum[$n]}, \"port_number\": ${portnum[$n]}}"
[[ $n -eq 0 ]] && RAWJSONPOSTDATA="${RAWJSONPOSTDATA},"
done
RAWJSONPOSTDATA="${RAWJSONPOSTDATA}]}"
echo -e "${YELLOW}${BOLD}rawjson is:\n${RAWJSONPOSTDATA}${PLAIN}" >/dev/stderr
actiontargets="$curlocs,,,"
fi
elif [[ $actionname == "mv" ]]; then
oldname=$(echo "$data" | awk -F, '{ print $2 }' | sort -u)
olduuid=$(echo "$data" | awk -F, '{ print $3 }' | sort -u)
@ -2361,14 +2518,13 @@ debug " opts = ${opts[@]}"
debug " outputfile = ${TMPFILE}"
runaction ${endpoint} $actionname "$actiontargets" ${opts[@]} >"$TMPFILE"
rv=$?
if [[ $actionname == "add" && $rv -eq 0 && $builtin -eq 0 ]]; then
if [[ $actionname == "add" && $origendpoint == "node" && $rv -eq 0 && $builtin -eq 0 ]]; then
local fail=0
# we now need to rename the newly created object - gns3
# will always generate a name based on the template
debug "json is $JSON_RESULTS"
json_extract "$JSON_RESULTS" .name oldname .node_id olduuid
if [[ $? -eq 0 ]]; then
info "Now need to rename '$oldname' to '$newname'..."
runaction ${origendpoint} mv "$curlocs,$oldname,$olduuid,name:$newname^" -F
[[ $? -ne 0 ]] && fail=1
else
@ -2598,6 +2754,13 @@ LINK="$BLUE$UNDERLINE"
UNDERLINE_PRINTED=$(echo -en "$UNDERLINE")
UNDERLINE_LENGTH=${#UNDERLINE_PRINTED}
NOMULTI=0
MULTI=1
NOQUOTES=0
QUOTES=1
REALLYNOQUOTES=-1
CURLERRORSTRINGS="(^40.:|error|status.*40.)"
# Generate sed script to add colours to certain words
@ -2635,8 +2798,9 @@ addendpoint nodes projects/_CURPROJECT_/nodes node node_id name
addendpoint links projects/_CURPROJECT_/links link link_id link_id
addepalias links l
addeptitles links "Type" "A-Host_UUID " "A-Port" "Z-Host_UUID " "Z-Port"
addepfields links ".link_type" ".nodes[0].node_id" ".nodes[0].label.text" ".nodes[1].node_id" ".nodes[1].label.text"
addeptitles links "Type" "A-Host_UUID " "A-Port" "Z-Host_UUID " "Z-Port" "ID _"
addepfields links ".link_type" ".nodes[0].node_id" ".nodes[0].label.text" ".nodes[1].node_id" ".nodes[1].label.text" ".link_id"
addepactions links add del
addendpoint models templates model template_id name
addepalias models m
@ -2663,7 +2827,7 @@ addcmd show "Show detail of a given element (eg. compute node, VM, etc)" 2 sh
addcmd net "Show network diagram (requires perl Graph::Easy)"
addcmd action "Perform action on given object." 3 act do
addcmd action "Perform action on given object" 3 act do
declare -a lines
for x in ${!ep_jqobj[@]}; do
if [[ -z ${ep_validactions[$x]} ]]; then
@ -2672,7 +2836,7 @@ addcmd action "Perform action on given object." 3 act do
lines+=("${ep_jqobj[$x]} actions: ${ep_validactions[$x]}")
fi
done
addcmdusage action "object_type action_type regexp_filter" "object_type can be: [${ep_jqobj[*]}]" "" "${lines[@]}"
addcmdusage action "object_type action_type regexp_filter [extrainfo]" "object_type can be: [${ep_jqobj[*]}]" "" "${lines[@]}"
addcmdoption action "-f" "Force - don't ask for confirmation"
addcmdalias "open" "action project open" "_CURPROJECT_"
@ -2685,6 +2849,9 @@ addcmdalias "add" "action node add" ""
addcmdalias "rm" "action node del" ""
addcmdalias "del" "action node del" ""
addcmdalias "mv" "action node mv" ""
addcmdalias "link" "action link add" ""
addcmdalias "unlink" "action link del" ""
addcmdalias "delink" "action link del" ""
addcmd help "List regular commands" 0 "?" "h"
addcmd exit "Exit from gnscli" 0 quit
@ -2776,12 +2943,13 @@ notify "Getting initial projectlist"
oldverbose=$VERBOSE
VERBOSE=1
errfile="$TMPDIR"/err
output=$(getdata projects show -e -r 2>"$errfile")
output=$(getdata projects list -e -r 2>"$errfile")
rv=$?
debug "rv is $rv"
VERBOSE=$oldverbose
if [[ $rv -eq 0 ]]; then
ok
#cat "$errfile"
cat "$errfile"
rm -f "$errfile"
jqoutput=$(echo "$output" | jq -r '.[] | .project_id + "|" + .name' 2>"$errfile")
rv=$?
@ -2915,10 +3083,10 @@ END {
"UUID#" + .link_id,
"Type#" + .link_type,
"Project UUID#" + .project_uuid,
"A-Node#" + .node[0].node_id,
"A-Port#" + .node[0].label.text,
"Z-Node#" + .node[1].node_id,
"Z-Port#" + .node[1].label.text,
"A-Node#" + .nodes[0].node_id,
"A-Port#" + .nodes[0].label.text,
"Z-Node#" + .nodes[1].node_id,
"Z-Port#" + .nodes[1].label.text,
"Capturing#" + (.capturing|tostring),
"Suspended#" + (.suspend|tostring),
"__END__"