diff --git a/gnscli.sh b/gnscli.sh
index 22356dc..9a6d4fc 100755
--- a/gnscli.sh
+++ b/gnscli.sh
@@ -1,5 +1,10 @@
#!/bin/bash
+# add node
+# issue with json post data
+# rename project
+# delete node
+
# node stop givesjq error
# connect xxx & [opens iterm (or whatever)]
@@ -300,8 +305,18 @@ function profile() {
}
function debug() {
+ local force=0
+ if [[ $1 == "-f" ]]; then
+ shift
+ force=1
+ fi
if [[ $VERBOSE -eq 1 ]]; then
- echo -e "${PURPLE}${BOLD}${FUNCNAME[1]}(): ${PLAIN}${PURPLE}$*${PLAIN}" 1>&2
+ 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
fi
}
@@ -755,21 +770,51 @@ function runcurlget() { # location api_endpoint(ovname)
return $rv
}
-function runcurlaction() { # location api_endpoint(ovname) obname ovmethod
+function runcurldatapost() { # location api_endpoint "curl data"
local thisapi thisurl curlres rv
- #local thisauthdom u p thisauthstr
local loc api_endpoint obname ovmethod
- #local data=""
local data=""
loc="$1"
api_endpoint="$2"
- obname="$3"
- ovmethod="$4"
+ data="$3"
thisapi=$(get $loc api)
[[ -z $thisapi ]] && echo "cant find api for '$loc'" && return 1
#thisauthdom=$(get $loc authdomain)
- thisurl="$thisapi/$api_endpoint/$obname/$ovmethod"
+debug -f "data is $data"
+ thisurl="$thisapi/$api_endpoint"
+ thisurl=${thisurl/_CURPROJECT_/$curprojid}
+
+ debug -f "curl -XPOST -sk --header 'Content-type: application/xml' --header 'Accept: application/json' -d \"$data\" $thisurl"
+set -x
+ curlres=$(curl -XPOST -sk --header 'Content-type: application/xml' --header 'Accept: application/json' -d "$data" $thisurl)
+set +x
+
+ rv=$?
+ [[ $rv -ne 0 ]] && error "curl POST to $thisurl failed"
+
+ echo "$curlres"
+ return $rv
+}
+
+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 data=""
+ #local data=""
+ loc="$1"
+ api_endpoint="$2"
+ obname="$3"
+ ovmethod="$4"
+ data="$5"
+ 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/$obname"
+ [[ -n $ovmethod ]] && thisurl="${thisurl}/$ovmethod"
thisurl=${thisurl/_CURPROJECT_/$curprojid}
#u=$(head -1 "$AUTHFILE")
#p=$(tail -1 "$AUTHFILE")
@@ -777,7 +822,7 @@ function runcurlaction() { # location api_endpoint(ovname) obname ovmethod
#unset u
#unset p
- [[ $VERBOSE -eq 1 ]] && debug "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"
curlres=$(curl -XPOST -sk --header 'Content-type: application/xml' --header 'Accept: application/json' -d "$data" $thisurl)
rv=$?
@@ -830,6 +875,7 @@ function getgnsmethod() {
close) echo "close";;
start) echo "start";;
stop) echo "stop";;
+ add) echo "";;
#migrate) echo "migrate";;
*)
echo
@@ -839,10 +885,26 @@ function getgnsmethod() {
return $rv
}
-function runaction_loc() { # runaction_loc syd|etc api_endpoint action_name ob_uuid ob_name [options]
+function makejson() { # makejson key1:val1^key2:val2^...
+ local plaindata tok toks key val tnum=1
+ plaindata="$1"
+ printf "%s" '{'
+ IFS='^' read -ra toks <<< "$plaindata"
+ for tok in "${toks[@]}"; do
+ [[ $tnum -ne 1 ]] && printf "%s" ","
+ key=${tok%:*}
+ val=${tok#*:}
+ printf '"%s":"%s"' "$key" "$val"
+ tnum=$((tnum + 1))
+ done
+ printf "%s\n" '}'
+}
+
+function runaction_loc() { # runaction_loc syd|etc api_endpoint action_name ob_uuid ob_name "extra info" [options]
local thisgrid thisauthdom thisurl thisauthstr curlres loc u p
local api_endpoint jq_obj opts opts_arr deffield epidx r1 r2 rv
local actionname method trv extrainfo
+ local curldata="" crv
rv=0
loc="$1"
@@ -861,6 +923,12 @@ 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"
+ if [[ $actionname == "add" ]]; then
+ curldata=$(makejson "$extrainfo")
+ fi
+
# special case
if [[ $actionname == "connect" ]]; then
local locidx
@@ -895,18 +963,25 @@ function runaction_loc() { # runaction_loc syd|etc api_endpoint action_name ob_u
return 1
fi
- debug "location: ${loc}"
- debug "api endpoint: ${api_endpoint}"
- debug "jq obj: ${jq_obj}"
- debug "actionname: ${actionname} (gns method: $method)"
- debug "obname: ${ob}"
- debug "options: ${opts}"
+ 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 "options: ${opts}"
+ debug -f "curldata: ${curldata}"
- curlres=$(runcurlaction $loc $api_endpoint $ob $method )
- if [[ $? -ne 0 ]]; then
+ if [[ $action == "add" ]]; then
+ curlres=$(runcurldatapost $loc $api_endpoint "$curldata" )
+ crv=$?
+ else
+ curlres=$(runcurlaction $loc $api_endpoint $ob $method "$curldata" )
+ crv=$?
+ fi
+ if [[ $crv -ne 0 ]]; then
rv=1
fi
- debug "curlres is [$curlres]"
+ debug -f "curlres is [$curlres]"
echo "$curlres"
fi
return $rv
@@ -1193,7 +1268,6 @@ function runaction() { # runaction targetlist optio
epidx=$(getepidx $what)
[[ $? -ne 0 ]] && error "unknown endpoint '$what'" && return 1
-
jq_obj="${ep_jqobj[$epidx]}"
api_endpoint="${ep_apiendpoint[$epidx]}"
[[ -z $api_endpoint ]] && error "no endpointname for endpoint '$what'" && return 1
@@ -1211,16 +1285,17 @@ debug "opts is $opts"
loc=$(echo "$line" | cut -d, -f1)
ob=$(echo "$line" | cut -d, -f2)
obuuid=$(echo "$line" | cut -d, -f3)
- extrainfo=$(echo "$line" | cut -d, -f4)
- runaction_loc $loc $epidx $actionname $obuuid $ob $extrainfo $opts > "$TMPDIR/run,$loc,$ob"
+ extrainfo="$(echo "$line" | cut -d, -f4-)"
+ runaction_loc $loc $epidx $actionname $obuuid $ob "$extrainfo" $opts > "$TMPDIR/run,$loc,$ob"
else
pids=""
while read -r line ; do
loc=$(echo "$line" | cut -d, -f1)
ob=$(echo "$line" | cut -d, -f2)
obuuid=$(echo "$line" | cut -d, -f3)
- extrainfo=$(echo "$line" | cut -d, -f4)
- runaction_loc $loc $epidx $actionname $obuuid $ob $extrainfo $opts > "$TMPDIR/run,$loc,$ob" &
+ extrainfo=$(echo "$line" | cut -d, -f4-)
+debug "extrainfo is: $extrainfo"
+ runaction_loc $loc $epidx $actionname $obuuid $ob "$extrainfo" $opts > "$TMPDIR/run,$loc,$ob" &
pids="$pids $!"
done <<< "$targetlist"
@@ -1236,7 +1311,7 @@ debug "opts is $opts"
# Capitalise first letter
objecttype=$(echo ${what:0:1} | tr '[a-z]' '[A-Z]')${what:1}
allgoodresults="Server,${objecttype},Job Status"
- allbadresults="Server,${objecttype},Detail,Reason,Status"
+ allbadresults=""
for f in ${!files[@]} ; do
local thiscsv
thisfile="${files[$f]}"
@@ -1255,12 +1330,15 @@ debug "opts is $opts"
goterror=1
elif [[ ${ACTIONRES_MSG[$n]} == *rror* ]]; then
goterror=1
+ elif [[ ${ACTIONRES_MSG[$n]} == *message* ]]; then
+ goterror=1
else
goterror=0
fi
if [[ $goterror -eq 1 ]]; then
- thiscsv_bad=$(echo "${ACTIONRES_MSG[$n]}" | jq -r "${jqf_bad}" | sed -e "s/_DC_/${ACTIONRES_LOC[$n]}/g" | sed -e "s/_OB_/${ACTIONRES_OB[$n]}/" | tr -d '"[]' | egrep -v "^$")
+ #thiscsv_bad=$(echo "${ACTIONRES_MSG[$n]}" | jq -r "${jqf_bad}" | sed -e "s/_DC_/${ACTIONRES_LOC[$n]}/g" | sed -e "s/_OB_/${ACTIONRES_OB[$n]}/" | tr -d '"[]' | egrep -v "^$")
+ thiscsv_bad=$(echo "${ACTIONRES_MSG[$n]}" | jq -r . | sed -e "s/_DC_/${ACTIONRES_LOC[$n]}/g" | sed -e "s/_OB_/${ACTIONRES_OB[$n]}/" | egrep -v "^$")
allbadresults="${allbadresults}\n${thiscsv_bad}"
errs=$((errs + 1))
@@ -1277,9 +1355,10 @@ debug "opts is $opts"
echo
if [[ $errs -gt 0 ]]; then
local fullres_bad
- echo -e "${RED}$errs x '${BOLD}$actionname${PLAIN}${RED}' actions failed.${PLAIN}"
- fullres_bad=$(csv_to_table $(($errs + 1)) "$allbadresults")
- echo "$fullres_bad"
+ echo -e "${RED}$errs x '${BOLD}$actionname${PLAIN}${RED}' actions failed:${PLAIN}"
+ echo -e "${RED}"
+ echo "$allbadresults" | sed -e 's/^/ /'
+ echo -e "${PLAIN}"
echo
fi
@@ -1327,7 +1406,7 @@ function getdata() { # getdata options
local usecache refilter
local w greenwords yellowwords redwords uuidcol
local errordebug=0
- local quiet=0
+ local quiet=0 ignorecase=0
start=$(($(gdate +%s%N)/1000))
lastqsecs=""
@@ -1358,6 +1437,7 @@ function getdata() { # getdata options
arraycontains opts_a "-q" && quiet=1
arraycontains opts_a "-v" && outmode=verbose
arraycontains opts_a "-s" && outmode=namesonly
+ arraycontains opts_a "-c" && ignorecase=1
arraycontains opts_a "-n" && usecache=0 || usecache=1
arraycontains opts_a "-e" && errordebug=1
@@ -1368,7 +1448,16 @@ debug "opts is $opts"
refilter=$(getarrayopt opts_a f)
[[ $refilter == "*" ]] && refilter=".*"
- [[ -n $refilter ]] && obfilter="select(.name|test(\"^$refilter$\"))" || obfilter="."
+ if [[ -n $refilter ]]; then
+ obfilter="select(.name|test(\"^$refilter$\""
+ if [[ $ignorecase -eq 1 ]]; then
+ obfilter="${obfilter}; \"i\"))"
+ else
+ obfilter="${obfilter}))"
+ fi
+ else
+ obfilter="."
+ fi
[[ -n $refilter ]] && [[ $quiet -eq 0 ]] && info "${what} filter: ^$refilter$"
# Allow standard globs rather than regexp globs
@@ -1667,7 +1756,7 @@ 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
+ local epidx endpoint newname newtype newtype_uuid
cmd=$1
shift
arg="$*"
@@ -1746,20 +1835,43 @@ debug "post replacedargs is [$replacedargs]"
fi
obname="" # global
if [[ $cmd == "show" ]]; then
- whattolist=${arg_array[0]} && unset 'arg_array[0]'
+ endpoint=${arg_array[0]} && unset 'arg_array[0]'
+ whattolist=${endpoint}
[[ ${#arg_array[@]} -ge 1 ]] && opts+=("-f${arg_array[@]}")
elif [[ $cmd == "list" ]]; then
- whattolist=${arg_array[0]} && unset 'arg_array[0]'
+ endpoint=${arg_array[0]} && unset 'arg_array[0]'
+ whattolist=${endpoint}
[[ ${#arg_array[@]} -ge 1 ]] && opts+=("-f${arg_array[@]}")
elif [[ $cmd == "action" ]]; then
- whattolist=${arg_array[0]} && unset 'arg_array[0]'
+ endpoint=${arg_array[0]} && unset 'arg_array[0]'
+ whattolist=${endpoint}
actionname=${arg_array[1]} && unset 'arg_array[1]'
- if [[ ${#arg_array[@]} -ge 1 ]]; then
- actionfilter="-f${arg_array[@]}"
- obname="${arg_array[@]}"
+ 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}"
+
+
+
+
else
- error "Name of $whattolist not provided."
- return 1
+ # start/stop/etc
+ if [[ ${#arg_array[@]} -ge 1 ]]; then
+ actionfilter="-f${arg_array[@]}"
+ obname="${arg_array[@]}"
+ else
+ error "Name of $whattolist not provided."
+ return 1
+ fi
fi
fi
@@ -1826,32 +1938,27 @@ debug "post replacedargs is [$replacedargs]"
action)
# TODO: ooremove any output format opts
- validate_action ${whattolist} $actionname
+ validate_action ${endpoint} $actionname
if [[ $? -ne 0 ]]; then
- error "'$actionname' is not a valid action for ${whattolist}s"
+ error "'$actionname' is not a valid action for ${endpoint}s"
return 1
fi
- epidx=$(getepidx $whattolist)
+ epidx=$(getepidx $endpoint)
if [[ $? -ne 0 ]]; then
- error "'$whattolist' is not a valid endpoint"
+ error "'$endpoint' is not a valid endpoint"
return 1
fi
- # When getting a list of what to operate on, we need
- # to get the ID as well as the name, and the ID field
- # depends on the obejct type.
- #action_idfield=${ep_idfield[$epidx]}
-
# Get a list of objects to operate on
# ie. turn regexp into a list of dcs and obnames first
- getdata ${whattolist} list $actionfilter $showerroropt -s -q >"$TMPFILE"
+ getdata ${whattolist} list $actionfilter $showerroropt -c -s -q >"$TMPFILE"
rv=$?
if [[ $rv -ne 0 ]]; then
- error "Query for matching objects failed."
+ error "Query for matching ${whattolist}s failed."
rv=1
elif [[ ! -e $TMPFILE ]]; then
- error "No matching objects found."
+ error "No matching ${whattolist}s found."
rv=1
elif grep -q "no results" $TMPFILE; then
error "No ${whattolist}s found matching '$obname'."
@@ -1879,6 +1986,71 @@ debug "tmpfile contents: [$(cat $TMPFILE)]"
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))
+ 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"
+ fi
+ if [[ -z $newtype ]]; then
+ confirm=0
+ else
+ notify_nodots "Adding a new ${BOLD}$newtype${PLAIN}${PURPLE} named $BOLD$newname${PLAIN}"
+ confirm=1
+ fi
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}\"}"
@@ -1898,7 +2070,19 @@ debug "tmpfile contents: [$(cat $TMPFILE)]"
fi
if [[ $confirm -eq 1 ]]; then
- actiontargets=$(echo "$data")
+ 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 }')
@@ -1912,12 +2096,12 @@ debug "tmpfile contents: [$(cat $TMPFILE)]"
rm -f "$TMPFILE"
debug "about to call runaction with:"
-debug " whattolist = $whattolist"
+debug " obtype = $endpoint"
debug " actionname = $actionname"
debug " actiontargets = $actiontargets"
debug " opts = ${opts[@]}"
debug " outputfile = ${TMPFILE}"
- runaction ${whattolist} $actionname "$actiontargets" ${opts[@]} >"$TMPFILE"
+ runaction ${endpoint} $actionname "$actiontargets" ${opts[@]} >"$TMPFILE"
rv=$?
if [[ $actionname != "connect" ]]; then
ok
@@ -2124,7 +2308,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
+ addepactions nodes start stop connect add
addendpoint links projects/_CURPROJECT_/links link link_id link_id
addepalias links l
@@ -2167,6 +2351,7 @@ addcmdalias "start" "action node start" ""
addcmdalias "stop" "action node stop" ""
addcmdalias "connect" "action node connect" ""
addcmdalias "c" "action node connect" ""
+addcmdalias "add" "action node add" ""
addcmd help "List regular commands" 0 "?" "h"
addcmd exit "Exit from gnscli" 0 quit