Skip to content

Instantly share code, notes, and snippets.

@mems
Forked from mousavian/akamai.api.sh
Last active June 9, 2023 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mems/4f06a9ae4a24c8d7c68ee0f46bbb2f3b to your computer and use it in GitHub Desktop.
Save mems/4f06a9ae4a24c8d7c68ee0f46bbb2f3b to your computer and use it in GitHub Desktop.
Akamai Open API with Bash
#!/usr/bin/env bash
# See also https://github.com/akamai/akamaipowershell
usage() {
cat <<EOT
Usage: $(basename $0) -X value -s value -t value -a value -u value [-d value] [-h]
Options:
-s Client secret
-t Client token
-a Access token
-d Request body
-u URL
-d Body or use stdin
-h Print this help
EOT
}
while getopts ":s:t:a:d:X:u:h" opt; do
case $opt in
s)
client_secret=$OPTARG
;;
t)
client_token=$OPTARG
;;
a)
access_token=$OPTARG
;;
d)
body=$OPTARG
;;
X)
method="${OPTARG^^}"
;;
u)
url=$OPTARG
;;
h)
usage
exit 0
;;
\?)
echo "Invalid option: -$OPTARG" >&2
usage
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
usage
exit 1
;;
esac
done
if [ -z "${client_secret+x}" ]; then
echo "Invalid option: -s" >&2
exit 1
fi
if [ -z "${client_token+x}" ]; then
echo "Invalid option: -t" >&2
exit 1
fi
if [ -z "${access_token+x}" ]; then
echo "Invalid option: -a" >&2
exit 1
fi
if [ -z "${body+x}" ]; then
# Use stdin instead
body=$(cat)
fi
if [ \( -z "${method+x}" \) -o \( "$method" != "GET" -a "$method" != "PUT" -a "$method" != "POST" -a "$method" != "DELETE" \) ]; then
echo "Invalid option: -X" >&2
exit 1
fi
if [ -z "${url+x}" ]; then
echo "Invalid option: -u" >&2
exit 1
fi
shift $((OPTIND-1))
timestamp=$(date -u +%Y%m%dT%H:%M:%S+0000)
# Pseudo random UUID
nonce=$(od -x /dev/urandom | head -1 | awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}')
# http or https
scheme="${url/:*/}"
# "https://www.example.com:443/api/v1/test?a=1" -> "www.example.com:443/api/v1/test?a=1"
proto_less="${url#*//}"
host="${proto_less%%/*}"
# FIXME KO with url="https://www.example.com:443" but OK with url="https://www.example.com:443/"
path_query="/${proto_less#*/}"
# Akamai EdgeGrid authentication
# See https://developer.akamai.com/legacy/introduction/Client_Auth.html
# https://techdocs.akamai.com/developer/docs/authenticate-with-edgegrid
# https://github.com/akamai/akamaipowershell/blob/master/shared/Invoke-AkamaiRestMethod.ps1#L124-L183
authorization="EG1-HMAC-SHA256 client_token=${client_token};access_token=${access_token};timestamp=${timestamp};nonce=${nonce};"
signing_key=$(echo -en "$timestamp" | openssl dgst -binary -sha256 -hmac "$client_secret" | base64)
body_hash=$(echo -en "$body" | shasum -a 256 --binary | cut -d " " -f 1 | xxd -r -p | base64)
data_to_sign="${method}\t${scheme}\t${host}\t${path_query}\t\t${body_hash}\t${authorization}"
signature=$(echo -en "$data_to_sign" | openssl dgst -binary -sha256 -hmac "$signing_key" | base64)
curl -i -X "$method" \
"$url" \
-H "Authorization: ${authorization}signature=${signature}" \
-H "Content-Type: application/json" \
-d "$body"
# Exemple of call invalidation API:
# HTTP/1.1 201 Created
# Allow: POST
# Content-Type: application/json
# X-RateLimit-Limit: 100
# X-Ratelimit-Limit-Objects: 10000
# X-Ratelimit-Limit-Per-Second: 50.00
# X-Ratelimit-Limit-Per-Second-Objects: 200.00
# X-RateLimit-Remaining: 99
# X-Ratelimit-Remaining-Objects: 9996
# Content-Length: 150
# Date: Mon, 03 Apr 2023 13:40:10 GMT
# Connection: keep-alive
#
# {"httpStatus":201,"detail":"Request accepted","supportId":"eiup-2faTJtfBD828q73pNeioSm","purgeId":"eiup-2faTJtfBD828q73pNeioSm","estimatedSeconds":5}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment