From 3db742aef18f752965ce9f58d2623fcc388838c1 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Mon, 3 Jan 2022 13:35:56 +1100 Subject: [PATCH] use a local numeric ID instead of long UUID to refer to links clean up action output --- gnscli.sh | 158 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 124 insertions(+), 34 deletions(-) diff --git a/gnscli.sh b/gnscli.sh index 231f50e..ee7c264 100755 --- a/gnscli.sh +++ b/gnscli.sh @@ -1,11 +1,5 @@ #!/bin/bash -# when listing links, use local numeric ID not UUID -# linkmapping[] ? -# or just order links are returned from api ? - - -# clean up action output # better cinfirmation when removing a link # rename node issue when matching multiple @@ -121,7 +115,12 @@ function cache_uuids() { # cache_uuids $$ [locations] curlres=$(runcurlget $loc $api_endpoint) [[ $? -ne 0 ]] && error "curl to $thisurl failed" && return 1 - echo "$curlres" | jq -r "try (.[] | [ .${ep_idfield[$epidx]}, .name ] | @csv) catch empty" | tr -d '"' >> "$thisfile" + + if [[ ${ep_name[$epidx]} == "links" ]]; then + echo "$curlres" | jq -r "try (. | to_entries | .[] | [ .value.${ep_idfield[$epidx]}, \"l\" + (.key|tostring) ] | @csv) catch empty" | tr -d '"' >> "$thisfile" + else + echo "$curlres" | jq -r "try (.[] | [ .${ep_idfield[$epidx]}, .name ] | @csv) catch empty" | tr -d '"' >> "$thisfile" + fi done done @@ -312,6 +311,10 @@ function profile() { [[ $PROFILING -eq 1 ]] && echo -e "${YELLOW}${BOLD}${FUNCNAME[1]}(): ${PLAIN}${YELLOW}$*${PLAIN}" 1>&2 } +function harddebug() { + echo -e "${YELLOW}${BOLD}$*${PlAIN}" >/dev/stderr +} + function debug() { local force=0 if [[ $1 == "-f" ]]; then @@ -489,6 +492,29 @@ function uuid_to_name() { return 1 } +function get_next_linkid() { + local x num max=-1 + for ((x=0; x<${#uuid_name[@]}; ++x)); do + if [[ "${uuid_name[$x]}" == l* ]]; then + num=${uuid_name[$x]/l/} + [[ $num -gt $max ]] && max=$num + fi + done + echo "l$((max + 1))" +} + +function name_to_uuid() { + local x + for ((x=0; x<${#uuid_name[@]}; ++x)); do + if [[ "${uuid_name[$x]}" == "$1" ]]; then + echo "${uuid_id[$x]}" + return 0 + fi + done + echo "$1" + return 1 +} + function uuid_to_idx() { local x for x in ${!uuid_id[@]}; do @@ -1027,6 +1053,7 @@ debug -f "arglist - extrainfo : $extrainfo" debug -f "arglist: remaining opts: $opts" if [[ $actionname == "add" || $actionname == "mv" ]]; then if [[ -n $RAWJSONPOSTDATA ]]; then +debug -f "using RAWJSONPOSTDATA for curldata" curldata="${RAWJSONPOSTDATA}" else curldata=$(makejson "$extrainfo") @@ -1298,7 +1325,12 @@ function getbasefilter() { # epidx [regexp_filter] filterarg="$*" [[ $filterarg == "*" ]] && filterarg=".*" - [[ -n "$*" ]] && refilter="select(.${ep_defaultfield[$epidx]}|test(\"^$*$\"))" || refilter="." + [[ -n "$filterarg" ]] && refilter="select(.${ep_defaultfield[$epidx]}|test(\"^$filterarg$\"))" || refilter="." + + #if [[ ${ep_name[$epidx]} == "links" ]]; then + # refilter="${refilter} | to_entries" + #fi + IFS='#' read -r -a titles <<< "${ep_titles[$epidx]}" IFS='#' read -r -a fields <<< "${ep_fields[$epidx]}" @@ -1492,7 +1524,7 @@ function runaction() { # runaction targetlist optio 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 local jqf_bad='[ "_DC_", "_OB_", .fault.detail, .fault.reason, .status ] | @csv' local objecttype extrainfo @@ -1566,11 +1598,33 @@ debug -f "--> extrainfo = $extrainfo" good=0 rv=0 + # Capitalise first letter objecttype=$(echo ${what:0:1} | tr '[a-z]' '[A-Z]')${what:1} + + [[ $objecttype == "Model" ]] && objecttype="Node" # oooo -# change this jq based on thr action - allgoodresults="Server,${objecttype},Job Status" + # figure out jq based on action + if [[ $actionname == "add" && $endpoint == "model" ]]; then + allgoodresults="Server,${objecttype},Ports" + jqf='[ "_DC_", "_OB_", .properties.adapters ] | @csv' + elif [[ $actionname == "add" && $endpoint == "link" ]]; then + local id + # hack: local ID won't be generated ubtil we + # recache, but weknow ot will be the last current + # id plus one. + id=$(get_next_linkid) + allgoodresults="Server,${objecttype},Predicted_ID" + jqf="[ \"_DC_\", .link_id, \"${id}\" ] | @csv" + elif [[ $actionname == "del" ]]; then + allgoodresults="" + jqf='' + else + allgoodresults="Server,${objecttype},JobStatus" + jqf='[ "_DC_", "_OB_", .status ] | @csv' + fi + + allbadresults="" for f in ${!files[@]} ; do local thiscsv @@ -1627,9 +1681,11 @@ debug -f "--> extrainfo = $extrainfo" local fullres echo -e "${GREEN}$good x '${BOLD}$actionname${PLAIN}${GREEN}' actions submitted successfully.${PLAIN}" - fullres=$(csv_to_table $(($good + 1)) "$allgoodresults") - - echo "$fullres" + # More than just a heading? + if [[ $(echo -e "$allgoodresults" | wc -l | bc) -gt 1 ]]; then + fullres=$(csv_to_table $(($good + 1)) "$allgoodresults") + echo "$fullres" + fi fi if [[ $good -ge 1 ]]; then @@ -2093,16 +2149,17 @@ function getnodetypeforadd() { # alluids # o_arr # ou_arr -function validate_action_obs() { # whattolist actionfilter showerroropt multiple_obs_allowed [retvar_selobname] [retvar_selobuuid] - local whattolist actionfilter showerroropt +function validate_action_obs() { # infoname whattolist actionfilter showerroropt multiple_obs_allowed [retvar_selobname] [retvar_selobuuid] + local infoname 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" + infoname="$1" + whattolist="$2" + actionfilter="$3" + showerroropt="$4" + multiallowed="$5" + retvar_obname="$6" + retvar_obuuid="$7" debug "whattolist=$whattolist" debug "actionfilter=$actionfilter" @@ -2111,6 +2168,7 @@ function validate_action_obs() { # whattolist actionfilter showerroropt multiple debug "retvar_obname=$retvar_obname" debug "retvar_obuuid=$retvar_obuuid" + notify "Validating ${infoname}" getdata ${whattolist} list "-f${actionfilter}.*" $showerroropt -c -s -q >"$TMPFILE" rv=$? debug "actionfilter=$actionfilter" @@ -2228,6 +2286,23 @@ function action_triggers_recache() { return $((1 - $trigger)) } +# populates global CLIDS_RES +function convert_link_ids() { # endpoint str + local u ep + ep="$1" + u="$2" + CLIDS_RES="" + if [[ $ep == "link" && ${u} == l* ]]; then + u=$(name_to_uuid ${u}) + if [[ $? -ne 0 ]]; then + error "Can't find link ID ${BOLD}$u${PLAIN}${RED} - recache (${ITALIC}\\c${PLAIN}${RED}) may be needed." + return 1 + fi + fi + CLIDS_RES="$u" + return 0 +} + function processcmd() { local cmd arg newarg rv newlocs x err admin idx opts pipe gotargs local whattolist actionname="" actionfilter="" @@ -2242,6 +2317,8 @@ function processcmd() { arg="$*" shift + RAWJSONPOSTDATA="" + [[ -z ${cmd:0:1} ]] && return 0 [[ ${cmd:0:1} == "#" ]] && return 0 @@ -2317,11 +2394,17 @@ debug "post replacedargs is [$replacedargs]" if [[ $cmd == "show" ]]; then endpoint=${arg_array[0]} && unset 'arg_array[0]' whattolist=${endpoint} - [[ ${#arg_array[@]} -ge 1 ]] && opts+=("-f${arg_array[@]}") + if [[ ${#arg_array[@]} -ge 1 ]]; then + convert_link_ids $endpoint "${arg_array[@]}" || return 1 + opts+=("-f${CLIDS_RES}") + fi elif [[ $cmd == "list" ]]; then endpoint=${arg_array[0]} && unset 'arg_array[0]' whattolist=${endpoint} - [[ ${#arg_array[@]} -ge 1 ]] && opts+=("-f${arg_array[@]}") + if [[ ${#arg_array[@]} -ge 1 ]]; then + convert_link_ids $endpoint "${arg_array[@]}" || return 1 + opts+=("-f${CLIDS_RES}") + fi elif [[ $cmd == "net" ]]; then whattolist="links" opts+="-e" @@ -2358,7 +2441,7 @@ debug "post replacedargs is [$replacedargs]" for x in 0 1; do dev[$x]=${arg_array[$idx]}; idx=$((idx + 1)) port[$x]=${arg_array[$idx]}; idx=$((idx + 1)) - # replace * with .* + # replace * with .* port[$x]=$(echo "${port[$x]}" | sed 's#[^\.]\*#\.\*#g') if [[ -z ${dev[$x]} || -z ${port[$x]} ]]; then failed=1 @@ -2368,16 +2451,21 @@ debug "post replacedargs is [$replacedargs]" error "usage: action link add adev aport zdev zport" return 1 fi + else + error "Don't know how to add a $endpoint yet" + return 1 fi elif [[ $actionname == "mv" ]]; then oldname=${arg_array[2]} newname=${arg_array[3]} actionfilter="-f.*${oldname}.*" else - # start/stop/etc + # start/stop/del/etc +# oooo does thiss work with multi args? if [[ ${#arg_array[@]} -ge 1 ]]; then - actionfilter="-f${arg_array[@]}" - obname="${arg_array[@]}" + convert_link_ids $endpoint "${arg_array[@]}" || return 1 + actionfilter="-f${CLIDS_RES}" + obname="${CLIDS_RES}" else error "Name of $whattolist not provided." return 1 @@ -2468,7 +2556,7 @@ debug "post replacedargs is [$replacedargs]" # ie. turn regexp into a list of dcs and obnames first echo if [[ $actionname == "connect" || $actionname == "mv" ]]; then - validate_action_obs ${whattolist} "$actionfilter" "$showerroropt" $NOMULTI || return $? + validate_action_obs "$whattolist name" ${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%,})" @@ -2478,7 +2566,7 @@ debug "post replacedargs is [$replacedargs]" fi elif [[ $actionname == "add" ]]; then if [[ $endpoint == "node" ]]; then - validate_action_obs ${whattolist} "$actionfilter" "$showerroropt" $NOMULTI newnodetype newnodetype_uuid + validate_action_obs "node type" ${whattolist} "$actionfilter" "$showerroropt" $NOMULTI newnodetype newnodetype_uuid if [[ -z $newnodetype ]]; then confirm=0 else @@ -2494,7 +2582,7 @@ debug "newnodeuuid is $newnodetype_uuid" 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 $? + validate_action_obs "${letter}-end" "node" "${dev[$x]}" "$showerroropt" $NOMULTI newn newu || return $? dev[$x]="$newn" devuuid[$x]="$newu" debug "${letter}-node ${dev[$x]} is OK (${dev[$x]})" @@ -2529,7 +2617,7 @@ debug "adapnumlist is $adapnumlist" confirm=1 fi else # action is not add/connect - validate_action_obs ${whattolist} "$actionfilter" "$showerroropt" $MULTI || return $? + validate_action_obs "${whattolist} name" ${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}\"}" @@ -2590,7 +2678,6 @@ debug "adapnumlist is $adapnumlist" [[ $n -eq 0 ]] && RAWJSONPOSTDATA="${RAWJSONPOSTDATA}," done RAWJSONPOSTDATA="${RAWJSONPOSTDATA}]}" -echo -e "${YELLOW}${BOLD}rawjson is:\n${RAWJSONPOSTDATA}${PLAIN}" >/dev/stderr actiontargets="$curlocs,,," fi @@ -2642,6 +2729,9 @@ debug " outputfile = ${TMPFILE}" if [[ $actionname != "connect" ]]; then ok [[ -e $TMPFILE ]] && cat "$TMPFILE" | $pipe + if [[ $actionname == "add" && $origendpoint == "link" && $rv -eq 0 ]]; then + warn "Use '${ITALIC}l l${PLAIN}${YELLOW}' to confirm predicted ID" + fi echo info $(printf "action submission time: %s seconds" "$lastqsecs") fi @@ -2932,7 +3022,7 @@ 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" "ID _" + addeptitles links "Type" "A-Host_UUID " "A-Port" "Z-Host_UUID " "Z-Port" "ID_UUID" 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 addepactionusage links "add" "a_nodename a_portname b_nodename b_portname"