Skip to content

Instantly share code, notes, and snippets.

@poggenpower
Last active November 3, 2023 14:59
Show Gist options
  • Save poggenpower/41c1ae10386a4bf6382bace696d27cfe to your computer and use it in GitHub Desktop.
Save poggenpower/41c1ae10386a4bf6382bace696d27cfe to your computer and use it in GitHub Desktop.
API wrapper for AQUA CSP
.aqua-token
payload*
post*
data*

API Wrapper

use this script to fiddle around with the AQUA Rest API. It requires only bash and curl to get it work (I know there are 100 better languages to do it, ...)

Features

  • send API commands to AQUA CSP either on-prem or SaaS
  • support for different Saas-Regions
  • Cache of auth token for quicker testing (Warnig token stored at disk and has a validity of 30 days) use -N to run without caching the token.

Usage

Usage: api_wrap.sh [-h] [-v] -H hostname [-c [REGION]] [-u user] command

Run a API command on Aqua Console.
Ask for pw if required. Caches token in .aqua-token for further calls.

Available options:

-h, --help      Print this help and exit
-v, --verbose   Print script debug info
-d, --delete-auth forget authentication token.
-N, --no-token  Don't cache token in .aqua-token
-H, --host      hostname of the aqua console (if not running on port 443 add ":####")
-u, --user      username to login to the console
-c, --cloud     login to cloud.aquasec.com
                give the region prefix like "eu-1" for Europe. Defaults is US
-q, --quite     suppress any messages from the script

command:
    test: check if authentication is passing otherwise ask for credentials
    get: API GET, return type json
        get local-part
        local-part: path+parameter
    delete: API DELETE, return type json
        delete local-part
        local-part: path+parameter
    put: API PUT, input via file
        put apipath file.json
        apipath: local part of the api route
        file.json: path to file containing json data to put
    post: API POST, input via file
        post apipath file.json
        apipath: local part of the api route
        file.json: path to file containing json data to post
    clear: delete cached token

    Result: (for pure output send: 2> /dev/null)"

Examples:
  Test if you can authenticate against a cloud tenant.
  # ./api_wrap.sh -H a24e9XXXXX.cloud.aquasec.com -c -u '[email protected]'  test

  Get all images without any log messages, to pipe into file or jq
  # ./api_wrap.sh -H myaqua.local.domain -u 'administrator' -q  get /api/v2/images
#!/usr/bin/env bash
set -euo pipefail
trap 'cleanup SIGINT $LINENO' SIGINT
trap 'cleanup SIGTERM $LINENO' SIGTERM
trap 'cleanup ERR $LINENO' ERR
CLOUD_AUTH_HOST="api.cloudsploit.com"
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P)
quiet=0
usage() {
cat <<EOF
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-v] -H hostname [-c [REGION]] [-u user] command
Run a API command on Aqua Console.
Ask for pw if required. Caches token in .aqua-token for further calls.
Available options:
-h, --help Print this help and exit
-v, --verbose Print script debug info
-d, --delete-auth forget authentication token.
-N, --no-token Don't cache token in .aqua-token
-H, --host hostname of the aqua console (if not running on port 443 add ":####")
-u, --user username to login to the console
-s, --schema default "https", use "http" for plain communication
-c, --cloud login to cloud.aquasec.com
give the region prefix like "eu-1" for Europe. Defaults is US (no prefix)
-q, --quite suppress any messages from the script
command:
test: check if authentication is passing otherwise ask for credentials
get: API GET, return type json
get local-part
local-part: path+parameter
delete: API DELETE, return type json
delete local-part
local-part: path+parameter
put: API PUT, input via file
put apipath file.json
apipath: local part of the api route
file.json: path to file containing json data to put
post: API POST, input via file
post apipath file.json
apipath: local part of the api route
file.json: path to file containing json data to post
clear: delete cached token
Result: (for pure output send: 2> /dev/null)"
Examples:
Test if you can authenticate against a cloud tenant.
# ./api_wrap.sh -H a24e9XXXXX.cloud.aquasec.com -c -u '[email protected]' test
Get all images without any log messages, to pipe into file or jq
# ./api_wrap.sh -H myaqua.local.domain -u 'administrator' -q get /api/v2/images
EOF
}
cleanup() {
# script cleanup here
die "Sig ${1} case by line no: ${2} Something went wrong, e.g. command with a non zero exit code: $?"
}
setup_colors() {
if [[ -t 2 ]] && [[ -z "${NO_COLOR-}" ]] && [[ "${TERM-}" != "dumb" ]]; then
NOFORMAT='\033[0m' RED='\033[0;31m' GREEN='\033[0;32m' ORANGE='\033[0;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' YELLOW='\033[1;33m'
else
NOFORMAT='' RED='' GREEN='' ORANGE='' BLUE='' PURPLE='' CYAN='' YELLOW=''
fi
}
msg() {
if [ "${quiet}" -eq 0 ]; then
echo >&2 -e "${1-}${NOFORMAT}"
fi
}
die() {
local msg=$1
local code=${2-1} # default exit status 1
msg "${RED}$msg"
exit "$code"
}
parse_params() {
# default values of variables set from params
del_auth=0
no_token=0
is_cloud=0
host=''
user=''
schema="https"
while :; do
case "${1-}" in
-h | --help) usage ;;
-v | --verbose) set -x ;;
--no-color) NO_COLOR=1 ;;
-d | --delete-auth) del_auth=1 ;;
-c | --could) is_cloud=1
if [[ ${2-NOTSET} != -* ]]; then
CLOUD_AUTH_HOST="${2}.${CLOUD_AUTH_HOST}"
shift
fi
msg "${YELLOW} authentication: ${CLOUD_AUTH_HOST}"
;;
-q | --quiet) quiet=1 ;;
-N | --no-token) no_token=1 ;;
-H | --host)
host="${2-}"
shift
;;
-u | --user)
user="${2-}"
shift
;;
-s | --schema)
schema="${2-}"
shift
;;
-?*) usage && die "Unknown option: $1" ;;
*) break ;;
esac
shift
done
args=("$@")
# check required params and arguments
[[ -z "${host-}" ]] && usage && die "Missing required parameter: 'hostname'."
[[ ${#args[@]} -eq 0 ]] && msg "command missing, run test" && args+="test"
return 0
}
run_commands(){
command="noop"
case "${1-}" in
clear)
delete_token;;
test)
login
if [ ${is_cloud} -eq 1 ]; then
cmd_generic GET "/v2/keys"
else
cmd_generic "GET" "/api/v1/servers"
fi
;;
get)
shift
login
cmd_generic "GET" $@;;
delete)
shift
login
cmd_generic "DELETE" "$@";;
put)
shift
login
cmd_generic "PUT" "$@";;
post)
shift
login
cmd_generic "POST" "$@";;
*) die "Unknown command $1" ;;
esac
}
read_token(){
if [[ -w .aqua-token && $no_token -eq 0 ]]; then
token_conf=$(cat .aqua-token)
user=${token_conf%|*}
TOKEN=${token_conf#*|}
fi
}
delete_token(){
if [ -w .aqua-token ]; then
rm .aqua-token
msg "${GREEN}Token removed."
else
if [ -e .aqua-token ]; then
msg "${RED}Can't delete cached token file .aqua-token"
fi
fi
}
auth() {
if [ -z ${user} ]; then
echo -n Username:
read user
fi
echo -n Password for ${user}:
read -s passwd
if [ "${is_cloud}" -eq 1 ]; then
api_url="https://${CLOUD_AUTH_HOST}/v2/signin"
login_data='{"email":"'${user}'","password":"'${passwd}'"}'
else
api_url="${schema}://${host}/api/v1/login"
login_data='{"id":"'${user}'","password":"'"${passwd}"'","remember":true}'
fi
set +e # allow non 0 exit code
TOKEN=$(curl -k -f "${api_url}" -H 'Connection: keep-alive' -H 'Accept: application/json, text/plain, */*' -H 'DNT: 1' -H 'Content-Type: application/json;charset=UTF-8' -H 'Accept-Language: en-GB,en-US;q=0.9,en;q=0.8,de;q=0.7' --data-raw "${login_data}" --compressed --insecure| sed 's/.*"token":"\{0,1\}\([^,"]*\)"\{0,1\}.*/\1/')
exit_code=$?
set -e
if [ ${exit_code} -eq 0 ]
then
if [ $no_token -eq 0 ]; then
umask 077
echo "${user}|${TOKEN}" > .aqua-token
msg "${GREEN}Login succesful, token cached"
else
msg "${GREEN}Login successful"
fi
else
die "Authentication not successful"
fi
}
make_URL() {
local regex='https?://[-[:alnum:]\+&@#/%?=~_|!:,.;]*[-[:alnum:]\+&@#/%=~_|].*'
if [[ $1 =~ $regex ]]; then
echo $1
else
echo "${schema}://${host}${1}"
fi
}
login() {
TOKEN="invalid"
if [ $del_auth -eq 0 ]; then
read_token
else
delete_token
fi
curl_param="-f"
if [ "${is_cloud}" -eq 1 ]; then
test_api="https://${CLOUD_AUTH_HOST}/v2/groups"
else
test_api="/api/v2/dashboards/Default"
fi
cmd_generic GET "${test_api}" # > /dev/null 2> /dev/null && true
if [ ${exit_code} -eq 0 ]
then
msg "${GREEN}Token valid"
else
auth
fi
}
# cmd_query(){
# args=($@)
# [[ ${#args[@]} -lt 2 ]] && die "Missing path&parameters"
# api_url=$(make_URL $2)
# echo $api_url
# set +e # allow non 0 exit code
# result=$(curl -k -s $curl_param --request ${1} --url ${api_url} -H 'Authorization: Bearer '${TOKEN} --header 'Accept: application/json')
# exit_code=$?
# msg "Query ${2} exit code ${exit_code}"
# set -e
# curl_param=''
# echo ${result}
# }
# cmd_send(){
# args=($@)
# [[ ${#args[@]} -lt 3 ]] && die "Missing parameters 3 expected path and filename"
# if [ -r ${3} ]; then
# inputfile=${3}
# else
# die "file ${3} not found or not readable"
# fi
# result=$(curl -k -s --request ${1} --url ${schema}://${host}${2} -H 'Authorization: Bearer '${TOKEN} --header 'Accept: application/json' -H 'Content-Type: application/json;charset=UTF-8' --data @${inputfile})
# echo ${result}
# }
cmd_generic(){
args=($@)
send_params=""
[[ ${#args[@]} -lt 2 ]] && die "Missing path&parameters"
if [[ ${args[3]+1} ]]; then
send_params="-H 'Content-Type: application/json;charset=UTF-8' --data @${args[3]}"
fi
api_url=$(make_URL $2)
set +e # allow non 0 exit code
result=$(curl -k -s $curl_param --request ${1} --url ${api_url} -H 'Authorization: Bearer '${TOKEN} --header 'Accept: application/json' $send_params)
exit_code=$?
msg "Query ${2} exit code ${exit_code}"
set -e
curl_param=''
echo ${result}
}
setup_colors
parse_params "$@"
run_commands ${args[@]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment