Showing posts with label REST API. Show all posts
Showing posts with label REST API. Show all posts

Thursday, February 28, 2019

How to perform Instance Actions (Instance Stop/Start) using REST API on Oracle Cloud Infrastructure Compute Instances

Hello,

Using REST API to interact with Oracle Cloud Infrastructure is highly desirable for programmatic access to OCI resources from your applications.

For performing instance actions such as STOP, START, RESET and others as mentioned in OCI API documentation [1], you need to pass the parameters as follows rather than via json file. Somehow, I am unable to pass the parameters using json file.

You could create an empty json file as follows and use it on the REST API Call.
 
Load oci-curl function:
# . ./oci-curl

 Create an empty JSON file as we need to use POST method:

# touch empty.json

Syntax:
#oci-curl iaas.us-ashburn-1.oraclecloud.com post ./empty.json "/20160918/instances/?instanceId=&action=STOP"


Refer OCI REST API documentation [2] for more details how to generate signature and authorization strings for accessing API.
 
A copy of the oci-curl script is provided below. You need to update the following parameters in the script though:
local tenancyId="ocid1.tenancy.oc1..aaaaaaaaoumXXXnhkrc72dn6wjs27gq";
local authUserId="ocid1.user.oc1..aaaaaaaa6dmk7XXXhfshe6cacmpt2tjmq";
local keyFingerprint="b3:8f:55:XX:XX:XX:XX:86:a9:be:d4";
local privateKeyPath="/Users/muyself/.oci/oci_api_key.pem";

I am passing the parameters to the rest endpoint after "?". Multiple parameters can be passed using "&".

In the above example, I am passing the 2 required parameters "instanceId" and "action" after ? Separated using &.


Example:
#oci-curl iaas.us-ashburn-1.oraclecloud.com post ./empty.json "/20160918/instances/ocid1.instance.oc1.iad.abuwcljtttj6sgpah77XXXXXXXXXwde5fhdy6apfu5mk7svvgigxq?instanceId=ocid1.instance.oc1.iad.abuwcljtttj6sgpah77XXXXXXXXXwsvvgigxq&action=STOP"

 

Here is the oci-curl script:

# Version: 1.0.2
# Usage:
# oci-curl <host> <method> [file-to-send-as-body] <request-target> [extra-curl-args]
#
# ex:
# oci-curl iaas.us-ashburn-1.oraclecloud.com get "/20160918/instances?compartmentId=some-compartment-ocid"
# oci-curl iaas.us-ashburn-1.oraclecloud.com post ./request.json "/20160918/vcns"
# oci-curl iaas.eu-frankfurt-1.oraclecloud.com post ./empty.json "/20160918/instances/ocid1.instance.oc1.eu-frankfurt-1.antheljt2nxxxxxud53gpggoryh2k?instanceId&action=START"

function oci-curl {
# TODO: update these values to your own
local tenancyId="ocid1.tenancy.oc1..aaaaaaaaouminldguXXXX6snhkrc72dn6wjs27gq";
local authUserId="ocid1.user.oc1..aaaaaaaadmkXXXXXXX2imyg23khy4vuuv6a5aytjmq";
local keyFingerprint="b3:8f:55:5e:xx:xx:xx:xx4:86:a9:be:d4";
local privateKeyPath="/Users/myself/.oci/oci_api_key.pem";

local alg=rsa-sha256
local sigVersion="1"
local now="$(LC_ALL=C \date -u "+%a, %d %h %Y %H:%M:%S GMT")"
local host=$1
local method=$2
local extra_args
local keyId="$tenancyId/$authUserId/$keyFingerprint"

case $method in

"get" | "GET")
local target=$3
extra_args=("${@: 4}")
local curl_method="GET";
local request_method="get";
;;

"delete" | "DELETE")
local target=$3
extra_args=("${@: 4}")
local curl_method="DELETE";
local request_method="delete";
;;

"head" | "HEAD")
local target=$3
extra_args=("--head" "${@: 4}")
local curl_method="HEAD";
local request_method="head";
;;

"post" | "POST")
local body=$3
local target=$4
extra_args=("${@: 5}")
local curl_method="POST";
local request_method="post";
local content_sha256="$(openssl dgst -binary -sha256 < $body | openssl enc -e -base64)";
local content_type="application/json";
local content_length="$(wc -c < $body | xargs)";
;;

"put" | "PUT")
local body=$3
local target=$4
extra_args=("${@: 5}")
local curl_method="PUT"
local request_method="put"
local content_sha256="$(openssl dgst -binary -sha256 < $body | openssl enc -e -base64)";
local content_type="application/json";
local content_length="$(wc -c < $body | xargs)";
;;

*) echo "invalid method"; return;;
esac

# This line will url encode all special characters in the request target except "/", "?", "=", and "&", since those characters are used
# in the request target to indicate path and query string structure. If you need to encode any of "/", "?", "=", or "&", such as when
# used as part of a path value or query string key or value, you will need to do that yourself in the request target you pass in.
local escaped_target="$(echo $( rawurlencode "$target" ))"

local request_target="(request-target): $request_method $escaped_target"
local date_header="date: $now"
local host_header="host: $host"
local content_sha256_header="x-content-sha256: $content_sha256"
local content_type_header="content-type: $content_type"
local content_length_header="content-length: $content_length"
local signing_string="$request_target\n$date_header\n$host_header"
local headers="(request-target) date host"
local curl_header_args
curl_header_args=(-H "$date_header")
local body_arg
body_arg=()

if [ "$curl_method" = "PUT" -o "$curl_method" = "POST" ]; then
signing_string="$signing_string\n$content_sha256_header\n$content_type_header\n$content_length_header"
headers=$headers" x-content-sha256 content-type content-length"
curl_header_args=("${curl_header_args[@]}" -H "$content_sha256_header" -H "$content_type_header" -H "$content_length_header")
body_arg=(--data-binary @${body})
fi

local sig=$(printf '%b' "$signing_string" | \
openssl dgst -sha256 -sign $privateKeyPath | \
openssl enc -e -base64 | tr -d '\n')

curl "${extra_args[@]}" "${body_arg[@]}" -X $curl_method -sS https://${host}${escaped_target} "${curl_header_args[@]}" \
-H "Authorization: Signature version=\"$sigVersion\",keyId=\"$keyId\",algorithm=\"$alg\",headers=\"${headers}\",signature=\"$sig\""
}

# url encode all special characters except "/", "?", "=", and "&"
function rawurlencode {
local string="${1}"
local strlen=${#string}
local encoded=""
local pos c o

for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] | "/" | "?" | "=" | "&" ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done

echo "${encoded}"
}
 
You may copy the oci-curl script and load it to the shell. After that you should be able to use REST API methods.    
 
This is an example of how to use REST API.