Note: This is not fully tested for all types of AWS services, or endpoints. If you run into any errors or have any questions, please open an issue or help us fix it with a PR!
This is a port of mhart/aws4 Node.js library for signing and preparing requests using AWS Signature Version 4. It replaces some of the Node.js specific functions with vanilla JavaScript, so it can be added to Runscope as a custom library, and used in pre-request scripts.
An example pre-request script using this library:
// GET http://s3.amazonaws.com
var opts = {service: 's3', path: request.path};
var awsObj = aws4.sign(opts, {accessKeyId: variables.get("AWS_ACCESS_KEY_ID"), secretAccessKey: variables.get("AWS_SECRET_ACCESS_KEY")});
request.path = awsObj.path;
for (var header in awsObj.headers) {
request.headers[header] = awsObj.headers[header];
}
There are 3 steps you need to follow to use this library:
- Download the aws4.js file and upload it as a custom library to your Runscope account
- Activate the library in your test's environment settings
- Edit the pre-request script of your test to sign your request and add the necessary headers to it
First, download the aws4.js file to your computer. Next, go to your Runscope account, click on your account's profile on the top-right and select "Script Library":
Then, next to the "Upload A Library" section, click on "Choose File", select the aws4.js file you previously downloaded, and then click on "Upload Script". You should see the new library in the "Existing Libraries" section, next to any other custom libraries you have previously uploaded:
Next, create a new test, or go to an existing test where you want to add a test step to one of AWS APIs and click on "Edit". Open your environment settings, and select "Script Libraries" on the left-hand side menu. You should see a list of all custom script libraries in your account, including the one we just uploaded. Toggle the aws4.js library on:
Now we need to open the test step with our request to an AWS API, and edit its pre-request script.
The usage of the library is the same as the one found in the original library's mhart/aws4 README.
First you need to create an object with your request information. For example, to make a request to the GET Bucket endpoint:
s3.amazonaws.com/{bucketName}
You would use the following pre-request script:
var opts = {service: 's3', path: request.path};
var awsObj = aws4.sign(opts, {accessKeyId: variables.get("AWS_ACCESS_KEY_ID"), secretAccessKey: variables.get("AWS_SECRET_ACCESS_KEY")});
request.path = awsObj.path;
for (var header in awsObj.headers) {
request.headers[header] = awsObj.headers[header];
}
To use the scripts, make sure you have two variables in your environment's "Initial Variables": AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
, with your AWS account's access key id and secret access key respectively.
GET http://s3.amazonaws.com
var opts = {service: 's3', path: request.path};
var awsObj = aws4.sign(opts, {accessKeyId: variables.get("AWS_ACCESS_KEY_ID"), secretAccessKey: variables.get("AWS_SECRET_ACCESS_KEY")});
request.path = awsObj.path;
for (var header in awsObj.headers) {
request.headers[header] = awsObj.headers[header];
}
GET http://s3.amazonaws.com/hitchikers-guide-to-the-galaxy?list-type=2&delimiter=/
var splitURL = request.url.split(/\/+/g);
var fullPath = "/"+splitURL[splitURL.length-1];
var opts = {service: 's3', path: fullPath};
var awsObj = aws4.sign(opts, {accessKeyId: variables.get("AWS_ACCESS_KEY_ID"), secretAccessKey: variables.get("AWS_SECRET_ACCESS_KEY")});
request.path = awsObj.path;
for (var header in awsObj.headers) {
request.headers[header] = awsObj.headers[header];
}
GET http://s3.amazonaws.com/hitchikers-guide-to-the-galaxy/dont-panic.txt
var opts = {service: 's3', path: request.path};
var awsObj = aws4.sign(opts, {accessKeyId: variables.get("AWS_ACCESS_KEY_ID"), secretAccessKey: variables.get("AWS_SECRET_ACCESS_KEY")});
request.path = awsObj.path;
for (var header in awsObj.headers) {
request.headers[header] = awsObj.headers[header];
}
PUT http://s3.amazonaws.com/hitchikers-guide-to-the-galaxy/file.txt
Select "+Add Body" and add Test Body
.
var opts = {service: 's3', path: request.path, method: request.method, body: request.body};
var awsObj = aws4.sign(opts, {accessKeyId: variables.get("AWS_ACCESS_KEY_ID"), secretAccessKey: variables.get("AWS_SECRET_ACCESS_KEY")});
request.path = awsObj.path;
for (var header in awsObj.headers) {
request.headers[header] = awsObj.headers[header];
}
// Build the path from the query strings defined in the test (library could probably do this)
// API docs for Cloudwatch: http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/Welcome.html
/*
Required params for SetAlarmState is:
* AlarmName
* StateReason
* StateValue
* Action (The operation name from the API docs, in this case SetAlarmState)
* Version (The API version to use. Defaults to an old version, so check the doc link for an appropriate version string. Note: The SetAlarmState action is not defined in the default API version.)
*/
var path = '/?';
for (var key in request.params) {
path += request.params[key].name + "=" + request.params[key].value + "&"; // Notice that there is currently no support for array values
}
// The service name for cloudwatch is 'monitoring'
// Change region if necessary. No region means default region
var opts = {service: 'monitoring', path: path, region: 'eu-west-1', method: request.method};
var awsObj = aws4.sign(opts, {accessKeyId: variables.get("AWS_ACCESS_KEY_ID"), secretAccessKey: variables.get("AWS_SECRET_ACCESS_KEY")});
request.path = awsObj.path;
// Paste the headers on to the request
for (var header in awsObj.headers) {
request.headers[header] = awsObj.headers[header];
}
var opts = {service: 'lambda', path: request.path, method: request.method, body: request.body, region: variables.get("region"), headers: request.headers};
var awsObj = aws4.sign(opts, {accessKeyId: variables.get("AWS_ACCESS_KEY_ID"), secretAccessKey: variables.get("AWS_SECRET_ACCESS_KEY")});
request.path = awsObj.path;
for (var header in awsObj.headers) {
request.headers[header] = awsObj.headers[header];
}
You can import the awsv4-runscope-sample.json file as a new test in one of your buckets to have the exact same requests as the examples included here. Just make sure to enable the custom library in your environment settings, include the AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
variables, and include your bucket name in any GET requests before running the tests.