So I wrote this script which has no external dependencies aside from its assumption that you either will set your API key, secret user key and CloudStack host URL in environment variables or hardcode them within the script. This script will work for any CloudStack API, e.g.,
cloudbasher listTemplates templatefilter=featuredNote that argument values containing spaces or shell meta characters should be quoted so as not to violate cloudbasher's assumption that its arguments each constitute a parameter=value pair.
:
set -o noglob
CS_APIKEY=${CS_APIKEY-your_value_here}
CS_ADMIN_SECRET_KEY=${CS_ADMIN_SECRET_KEY-your_value_here}
CS_URL=${CS_URL-your_value_here}
CS_RESPONSE_TYPE=${CS_RESPONSE_TYPE-json}
command=$1; shift
t=$TMP/cloudbasher.$$
trap "rm $t" 0
Uri_escape()
{
perl -MURI::Escape -ne 'chomp;print uri_escape($_),"\n"'
}
(
echo apiKey=$CS_APIKEY
echo command=$command
echo response=$CS_RESPONSE_TYPE
) > $t
while [ -n "$1" ]; do
echo "$1" >> $t
done
# other implementations URI encode the individual values for the
# parameters, but since the command and parameter names don't
# use reserved characters, we can just URI encode the entire
# thing safely; the one hitch is that this converts
# the '=' to %3D, but we can undo that w/ a quick sed call:
cat $t | Uri_escape | sed -e 's/%3D/=/' > $t.uri_encoded
trap "rm $t.uri_encoded" 0
all=`sort < $t.uri_encoded | tr '\n' '&' | sed -e 's/&$//'`
downcased_all=`echo -n "$all" | tr 'A-Z' 'a-z'`
base64_all_hashed=`echo -n "$downcased_all" | openssl dgst -sha1 -binary -hmac "$CS_ADMIN_SECRET_KEY" | base64`
signature=`echo -n "$base64_all_hashed" | Uri_escape`
url="$CS_URL/client/api?$all&signature=$signature"
curl -L --silent "$url"