#!/bin/sh
#       This file is part of anc-api-tools.
#
#       anc-api-tools is free software: you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation, either version 3 of the License, or
#       (at your option) any later version.
#
#       anc-api-tools is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#
#       You should have received a copy of the GNU General Public License
#       along with anc-api-tools.  If not, see <http://www.gnu.org/licenses/>.
#
#       Written by Atlantic.Net <see AUTHORS file for additional information>
#       for use with Atlantic.Net's Public Cloud - https://cloud.atlantic.net

ANC_VERSION="2010-12-30"
ANC_FORMAT="json" # Valid options are json or xml. Will only be used if Format=[json|xml] is not passed in via the command line eg: ./anc-list-instances Format=xml
ANC_BASE_URL="https://cloudapi.atlantic.net/?"
ANC_CURL_OPTIONS=""
ANC_WGET_OPTIONS="--quiet --output-document=-"

### Make sure ANC_ACCESS_KEY_ID is set:
if [ ! -n "${ANC_ACCESS_KEY_ID}" ]; then
	echo "Variable ANC_ACCESS_KEY_ID is not set. Please make sure the ANC_ACCESS_KEY_ID is set with the full path and file name of your ANC Access Key ID."
	exit 1
fi

### Make sure ANC_ACCESS_KEY_ID is readble:
if [ ! -r "${ANC_ACCESS_KEY_ID}" ]; then
	echo "ANC_ACCESS_KEY_ID file $ANC_ACCESS_KEY_ID is not readable by user $USER. Please make sure that the file set in variable ANC_ACCESS_KEY_ID is readable by $USER."
	exit 1
fi

### Put the ANC Access Key ID into a variable:
ANC_ACCESS_KEY_ID_VALUE="$(cat ${ANC_ACCESS_KEY_ID})"

### Make sure ANC_PRIVATE_KEY is set:
if [ ! -n "${ANC_PRIVATE_KEY}" ]; then
	echo "Variable ANC_PRIVATE_KEY is not set. Please make sure the ANC_PRIVATE_KEY is set with the full path and file name of your ANC Private Key."
	exit 1
fi

### Make sure ANC_PRIVATE_KEY is readble:
if [ ! -r "${ANC_PRIVATE_KEY}" ]; then
	echo "ANC_PRIVATE_KEY file $ANC_PRIVATE_KEY is not readable by user $USER. Please make sure that the file set in variable ANC_PRIVATE_KEY is readable by $USER."
	exit 1
fi

### Put the ANC Private Key into a variable:
ANC_PRIVATE_KEY_VALUE="$(cat $ANC_PRIVATE_KEY)"

### Convert the actions and verbs to a valid URL:
for ANC_OPTION in "$@"; do
        ### Split the verb from the action:
        ANC_VERB="`echo ${ANC_OPTION} | cut -d '=' -f 1`"
        ANC_ACTION="`echo ${ANC_OPTION} | cut -d '=' -f 2-`"

        ### URL encode the verb and the action:
        ANC_VERB="$(perl -MURI::Escape -e 'print uri_escape($ARGV[0]);' "${ANC_VERB}")"
        ANC_ACTION="$(perl -MURI::Escape -e 'print uri_escape($ARGV[0]);' "${ANC_ACTION}")"

        ### Rejoin the verb and the action:
        ANC_OPTIONS="${ANC_OPTIONS}${ANC_VERB}=${ANC_ACTION}&"
done

### Remove the last ampersand appended by the above for loop:
ANC_OPTIONS="$(echo $ANC_OPTIONS | sed 's/&$//')"

### Create the rndguid:
ANC_RNDGUID=$(uuidgen -r)

### Get the current unix timestamp:
ANC_SECONDS_SINCE_EPOCH=$(date +%s)

### Create the string that needs to be encoded to make the signature:
ANC_STRING_TO_SIGN=${ANC_SECONDS_SINCE_EPOCH}${ANC_RNDGUID}

### Create a hash of the signature using sha256 and then base64 encode the sha256 hash:
ANC_SIGNATURE=$(echo -n "${ANC_STRING_TO_SIGN}" | openssl dgst -sha256 -hmac "${ANC_PRIVATE_KEY_VALUE}" -binary | openssl enc -base64)

### URL encode the signature:
ANC_SIGNATURE="$(perl -MURI::Escape -e 'print uri_escape($ARGV[0]);' "${ANC_SIGNATURE}")"

### Create the full URL to call:
if echo "$*" | grep -q Format=; then
       	ANC_URL="${ANC_BASE_URL}&${ANC_OPTIONS}&Version=${ANC_VERSION}&ACSAccessKeyId=${ANC_ACCESS_KEY_ID_VALUE}&Timestamp=${ANC_SECONDS_SINCE_EPOCH}&Rndguid=${ANC_RNDGUID}&Signature=${ANC_SIGNATURE}"
else
    	ANC_URL="${ANC_BASE_URL}&${ANC_OPTIONS}&Format=${ANC_FORMAT}&Version=${ANC_VERSION}&ACSAccessKeyId=${ANC_ACCESS_KEY_ID_VALUE}&Timestamp=${ANC_SECONDS_SINCE_EPOCH}&Rndguid=${ANC_RNDGUID}&Signature=${ANC_SIGNATURE}"
fi

### Execute the command via curl:
curl ${ANC_CURL_OPTIONS} "${ANC_URL}"

### curl does not exist in this system's $PATH so execute the command via wget:
if [ $? -eq 127 ]; then
	wget ${ANC_WGET_OPTIONS} "{$ANC_URL}"
fi

## Both curl and wget do not exist in this system's $PATH. Notify the console and exit:
if [ $? -eq 127 ]; then
	echo "$0 version ${ANC_VERSION} error: Commands curl and wget not found in $PATH." >&2
	exit 1
fi
