diff options
Diffstat (limited to 'cac')
-rwxr-xr-x | cac | 492 |
1 files changed, 0 insertions, 492 deletions
@@ -1,492 +0,0 @@ -#! /bin/sh -# -#? cac - CloudAtCost command line interface -#? -#? Usage: -#? -set -euf - -#PATH=$PWD/bin:$PATH -#export PATH - -urlencode() { -#! /bin/sh -sed ' - s/%/%25/g - s/ /%20/g - s/!/%21/g - s/"/%22/g - s/#/%23/g - s/\$/%24/g - s/\&/%26/g - s/'\''/%27/g - s/(/%28/g - s/)/%29/g - s/\*/%2a/g - s/+/%2b/g - s/,/%2c/g - s/-/%2d/g - s/\./%2e/g - s/\//%2f/g - s/:/%3a/g - s/;/%3b/g - s//%3e/g - s/?/%3f/g - s/@/%40/g - s/\[/%5b/g - s/\\/%5c/g - s/\]/%5d/g - s/\^/%5e/g - s/_/%5f/g - s/`/%60/g - s/{/%7b/g - s/|/%7c/g - s/}/%7d/g - s/~/%7e/g -' -} -netmask_to_prefix() {( -#! /bin/sh -set -euf - -netmask=$1 - -binaryNetmask=$(echo $1 | sed 's/^/obase=2;/;s/\./;/g' | bc | tr -d \\n) -binaryPrefix=$(echo $binaryNetmask | sed -n 's/^\(1*\)0*$/\1/p') -if ! echo $binaryPrefix | grep -q .; then - echo $0: bad netmask: $netmask >&2 - exit 4 -fi -printf %s $binaryPrefix | tr -d 0 | wc -c -)} -# - -cac_resources_cache=${cac_resources_cache-$HOME/tmp/cac_resources_cache.json} -cac_servers_cache=${cac_servers_cache-$HOME/tmp/cac_servers_cache.json} -cac_tasks_cache=${cac_tasks_cache-$HOME/tmp/cac_tasks_cache.json} -cac_templates_cache=${cac_templates_cache-$HOME/tmp/cac_templates_cache.json} - -cac_secrets=${cac_secrets-$HOME/.secrets/cac} - - -. "$cac_secrets" >/dev/null 2>&1 || : - - -cac() { - __cac_cli__command=${1-help} - shift || : - __cac_cli__"$__cac_cli__command" "$@" -} - -#? cac help [REGEX] -#? Show help message. If a regex is specified, then show usage of matching -#? commands. -#? -__cac_cli__help() {( - regex=${1-} - - # test -t expects GNU coreutils - if test -t 0 >/dev/null 2>&1; then - filter() { - help=$(cat) - echo "$help" | - if test $(echo "$help" | wc -l) -gt $(tput lines); then - $PAGER "$@" - else - cat "$@" - fi - } - else - filter() { - cat "$@" - } - fi - if test -z "$regex"; then - sed -n ' - s/^#?\( \(.*\)\)\?/\2/p - ' - else - __cac_cli__help | sed -n ' - /^cac '"$regex"'/,/^$/p - ' - fi < "$0" | filter -)} - -#? cac console SERVERSPEC -#? Print console URL. -#? -__cac_cli__console() {( - server=$(__cac_cli__getserver "$1") - sid=$(echo $server | jq -r .sid) - # TODO check reply status == ok - _cac_post_api_v1 console sid="$sid" | jq -r .console -)} - -#? cac servers -#? Print cached servers JSON. -#? -__cac_cli__servers() { - jq -r . $cac_servers_cache -} - -#? cac tasks -#? Print cached tasks JSON. -#? -__cac_cli__tasks() { - jq -r . $cac_tasks_cache -} - -#? cac templates -#? Print cached templates JSON. -#? -__cac_cli__templates() { - jq -r . $cac_templates_cache -} - -#? cac resources -#? Print CloudPRO resources JSON. -#? -__cac_cli__resources() { - jq -r . $cac_resources_cache -} - -#? cac update -#? Fetch and cache state JSON. -#? -__cac_cli__update() {( - umask 0077 - for x in \ - resources \ - servers \ - tasks \ - templates \ - # This line intentionally left blank. - do - { - json=$(_cac_fetch_$x) - eval file=\$cac_${x}_cache - echo $json | jq . > "$file".tmp - mv "$file".tmp "$file" - } & - done - wait -)} - -#? cac getserver SERVERSPEC -#? Print cached server JSON. -#? -__cac_cli__getserver() {( - - case $1 in - *:*) - k=${1%%:*} - v=${1#*:} - ;; - *) - k=label - v=${1#*:} - ;; - esac - - if result=$(jq \ - -e \ - --arg k "$k" \ - --arg v "$v" \ - ' - map(select(.[$k]==$v)) | - if (. | length) == 1 then - .[0] - else - null - end - ' \ - $cac_servers_cache); then - echo $result | jq -r . - else - echo "$0 getserver $k:$v => not unique server found" >&2 - exit 23 - fi -)} - -#? cac generatenetworking SERVERSPEC -#? -__cac_cli__generatenetworking() {( - server=$(__cac_cli__getserver "$1") - - address=$(echo $server | jq -r .ip) - gateway=$(echo $server | jq -r .gateway) - nameserver=8.8.8.8 - netmask=$(echo $server | jq -r .netmask) - prefix=$(netmask_to_prefix $netmask) - - printf '_:\n' - printf '\n' - printf '{\n' - printf ' networking.interfaces.enp2s1.ip4 = [\n' - printf ' {\n' - printf ' address = "%s";\n' $address - printf ' prefixLength = %d;\n' $prefix - printf ' }\n' - printf ' ];\n' - printf ' networking.defaultGateway = "%s";\n' $gateway - printf ' networking.nameservers = [\n' - printf ' "%s"\n' $nameserver - printf ' ];\n' - printf '}\n' -)} - -#? cac powerop SERVERSPEC (poweron|poweroff|reset) -#? Activate server power operations. -#? -__cac_cli__powerop() {( - server=$(__cac_cli__getserver "$1") - action=$2 - - sid=$(echo $server | jq -r .sid) - - reply=$(_cac_post_api_v1 powerop sid="$sid" action="$action") - - _cac_handle_reply 'cac powerop' "$reply" -)} - -#? cac setlabel SERVERSPEC LABEL -#? -__cac_cli__setlabel() {( - server=$(__cac_cli__getserver "$1") - label=$2 - - sid=$(echo $server | jq -r .sid) - - reply=$(_cac_post_api_v1 renameserver sid="$sid" name="$label") - - _cac_handle_reply 'cac setlabel' "$reply" -)} - -#? cac setmode SERVERSPEC (normal|safe) -#? -__cac_cli__setmode() {( - server=$(__cac_cli__getserver "$1") - mode=$2 - - sid=$(echo $server | jq -r .sid) - - reply=$(_cac_post_api_v1 runmode sid="$sid" mode="$mode") - - _cac_handle_reply 'cac setmode' "$reply" -)} - -#? cac ssh SERVERSPEC -#? -__cac_cli__ssh() {( - server=$(__cac_cli__getserver "$1") - shift - - address=$(echo $server | jq -r .ip) - target=root@$address - - SSHPASS=$(echo $server | jq -r .rootpass) - export SSHPASS - - exec sshpass -e ssh \ - -S none \ - -o StrictHostKeyChecking=no \ - -o UserKnownHostsFile=/dev/null \ - $target \ - "$@" -)} - - -#? cac waitstatus SERVERSPEC ("Powered On"|...) -#? Blocks until server has specfied state. -#? -__cac_cli__waitstatus() { - server=$(__cac_cli__getserver "$1") - status=$(echo $server | jq -r .status) - - case $status in - $2) - return - ;; - esac - - echo "$(date -Is) Waiting for status: $2; current status: $status ..." >&2 - - __cac_cli__waitforcacheupdate __cac_cli__waitstatus "$@" -} - - -# XXX for __cac_cli__waitforcacheupdate and __cac_cli__poll cache means $cac_servers_cache - -#? cac waitforcacheupdate COMMAND [ARGS...] -#? Blocks until cache has been updated then executes "$@". -#? -__cac_cli__waitforcacheupdate() { - case $(inotifywait --format %f -q -e moved_to $(dirname $cac_servers_cache)) in - $(basename $cac_servers_cache)) "$@";; - *) __cac_cli__waitforcacheupdate "$@";; - esac -} - -#? cac poll [TIMESPEC=1m] -#? Continuously update cache, sleeping at least $1 between updates. -#? -__cac_cli__poll() { - __cac_cli__update - t=${1-1m} - echo "$(date -Is) cache updated; sleeping $t ..." >&2 - sleep "$t" - __cac_cli__poll "$@" -} - -#? cac build cpu=.. ram=.. storage=.. os=.. -#? Build a server from available resources. -#? cpu = 1/2/3/4/5/6/7/8 limit: 16 -#? ram = 1024 (must be multiple of 4. ex. 1024 / 2048 / 3096) limit: 32768 -#? storage = 10/20/30/40/50 ... etc limit: 1000 -#? os = 75 (must be an #id from `cac templates`) -#? -__cac_cli__build() {( - reply=$(export "$@"; _cac_post_api_v1 cloudpro/build \ - cpu="$cpu" \ - ram="$ram" \ - storage="$storage" \ - os="$os" \ - ) - - _cac_handle_reply 'cac build' "$reply" -)} - -#? cac delete SERVERSPEC -#? Delete / terminate server to add resources. -#? -__cac_cli__delete() {( - server=$(__cac_cli__getserver "$1") - sid=$(echo $server | jq -r .sid) - - reply=$(_cac_post_api_v1 cloudpro/delete sid="$sid") - - _cac_handle_reply 'cac delete' "$reply" -)} - - -#? -#? SERVERSPEC is a query like "mode:Safe", "sdate:08/04/2015", etc. -#? See `cac servers` to get an inspiration. -#? -#? See sleep(1) for TIMESPEC. -#? - -_cac_fetch_servers() {( - res=$(_cac_get_api_v1 listservers) - status=$(echo $res | jq -r .status) - - if [ "$status" = ok ]; then - echo "$res" | jq -r .data - else - echo "cac_fetch_servers: bad status: $status" >&2 - exit 1 - fi -)} - -_cac_fetch_tasks() {( - res=$(_cac_get_api_v1 listtasks) - status=$(echo $res | jq -r .status) - - if [ "$status" = ok ]; then - echo "$res" | jq -r .data - else - echo "cac_fetch_tasks: bad status: $status" >&2 - exit 1 - fi -)} - -_cac_fetch_templates() {( - res=$(_cac_get_api_v1 listtemplates) - status=$(echo $res | jq -r .status) - - if [ "$status" = ok ]; then - echo "$res" | jq -r .data - else - echo "cac_fetch_templates: bad status: $status" >&2 - exit 1 - fi -)} - -_cac_fetch_resources() {( - res=$(_cac_get_api_v1 cloudpro/resources) - status=$(echo $res | jq -r .status) - - if [ "$status" = ok ]; then - echo "$res" | jq -r .data - else - echo "cac_resources: bad cloudpro/resources status: $status" >&2 - exit 1 - fi -)} - - -# rsyncfiles : lines filename |> local-dir x rsync-target -> ? |> ? -rsyncfiles() {( - set -x - rsync \ - --rsync-path="mkdir -p \"$2\" && rsync" \ - -vzrlptD \ - --files-from=- \ - "$1"/ \ - "$2" -)} - - - - -_cac_handle_reply() {( - label=$1 - reply=$2 - - case $(echo $reply | jq -r .status) in - ok) - echo $reply | jq -r . >&2 - __cac_cli__update - ;; - *) - echo $label: bad reply: >&2 - echo $reply | jq -r . >&2 - exit 23 - ;; - esac -)} - - -_cac_get_api_v1() { - _cac_curl_api_v1 -G "$@" -} - -_cac_post_api_v1() { - _cac_curl_api_v1 -XPOST "$@" -} - -_cac_curl_api_v1() { - _cac_exec curl -sS "$1" "https://panel.cloudatcost.com/api/v1/$2.php" $( - shift 2 - set -- "$@" login="$cac_login" key="$cac_key" - for arg; do - echo -d $(printf '%s' "$arg" | urlencode) - done - ) -} - -_cac_exec() { - if test -z "${cac_via-}"; then - env -- "$@" - else - ssh -q "$cac_via" -t "$@" - fi -} - - - - - -case ${run-true} in - true) cac "$@";; -esac |