Skip to content

Commit

Permalink
Version 0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
bwbuchanan committed Mar 16, 2010
1 parent 8b0aa1f commit e22cce1
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 67 deletions.
23 changes: 23 additions & 0 deletions COPYRIGHT
@@ -0,0 +1,23 @@
Copyright (C) 2010 Brian Buchanan. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

5 changes: 5 additions & 0 deletions Makefile
@@ -0,0 +1,5 @@
all:
cd src && erl -make

clean:
rm -f ebin/*.beam
33 changes: 33 additions & 0 deletions README
@@ -0,0 +1,33 @@
erlcloud: Cloud Computing APIs For Erlang

This is version 0.1.0. The API is subject to change.

Currently, this library implements the Amazon Elastic Compute Cloud (EC2) API,
version 2009-11-30. All API functions have been implemented. Not all functions
have been tested, so exercise care when integrating this library into
production code. Please send bug reports and patches.

The library can be used two ways: either you can specify configuration
parameters in the process dictionary, or you can create a configuration object
and pass that to each request as the final parameter.

Per-process configuration:

erlcloud_aws:configure(AccessKeyId, SecretAccessKey [, Hostname])

Hostname defaults to "ec2.amazonaws.com".

Then you can simply call, e.g. erlcloud_ec2:describe_images().


Configuration object usage:

EC2 = erlcloud_ec2:new(AccessKeyId, SecretAccessKey [, Hostname])

erlcloud_ec2:describe_images(EC2).


For usage information, consult the source code and refer to the EC2 API reference at:

http://docs.amazonwebservices.com/AWSEC2/2009-11-30/APIReference/

2 changes: 1 addition & 1 deletion ebin/erlcloud.app
@@ -1,6 +1,6 @@
{application, erlcloud,
[{description, "Erlang cloud computing library"}m
{vsn, "0.1"},
{vsn, "0.1.0"},
{modules, []},
{registered, []},
{applications, [stdlib, kernel, sasl, crypto, ssl, inets]},
Expand Down
63 changes: 63 additions & 0 deletions include/erlcloud_ec2.hrl
@@ -0,0 +1,63 @@
-record(ec2_config, {host, access_key_id, secret_access_key}).
-type(proplist() :: [{atom(), term()}]).
-type(datetime() :: {{pos_integer(), 1..12, 1..31}, {0..23, 0..59, 0..60}}).
-type(ec2_shutdown_behavior() :: stop | terminate | undefined).
-type(ec2_volume_size() :: 1..1024).
-record(ec2_block_device_mapping, {
device_name::string(),
virtual_name::string(),
snapshot_id::string(),
volume_size::ec2_volume_size(),
delete_on_termination::boolean()
}).
-type(ec2_block_device_mapping() :: #ec2_block_device_mapping{}).
-record(ec2_instance_spec, {
image_id::string(),
min_count=1::pos_integer(),
max_count=1::pos_integer(),
key_name::string(),
group_set::[string()],
user_data::binary(),
instance_type::string(),
availability_zone::string(),
kernel_id::string(),
ramdisk_id::string(),
block_device_mapping::[ec2_block_device_mapping()],
monitoring_enabled=false::boolean(),
subnet_id::string(),
disable_api_termination=false::boolean(),
instance_initiated_shutdown_behavior::ec2_shutdown_behavior()
}).
-record(ec2_image_spec, {
image_location::string(),
name::string(),
description::string(),
architecture::string(),
kernel_id::string(),
ramdisk_id::string(),
root_device_name::string(),
block_device_mapping::[ec2_block_device_mapping()]
}).
-record(ec2_spot_instance_request, {
spot_price::string(),
instance_count=1::pos_integer(),
type=one_time::one_time|persistent,
valid_from::datetime(),
valid_until::datetime(),
launch_group::string(),
availability_zone_group::string(),
launch_specification::#ec2_instance_spec{}
}).
-record(ec2_ingress_spec, {
ip_protocol::tcp|udp|icmp,
from_port::-1 | 0..65535,
to_port::-1 | 0..65535,
source_security_group_owner_id::string(),
source_security_group_name::string(),
cidr_ip::string()
}).
-type(ec2_config() :: #ec2_config{}).
-type(ec2_image_spec() :: #ec2_image_spec{}).
-type(ec2_instance_spec() :: #ec2_instance_spec{}).
-type(ec2_ingress_spec() :: #ec2_ingress_spec{}).
-type(ec2_spot_instance_request() :: #ec2_spot_instance_request{}).
1 change: 1 addition & 0 deletions src/Emakefile
@@ -0,0 +1 @@
{'*', [{i, ["../include"]}, {outdir, "../ebin"}]}.
93 changes: 27 additions & 66 deletions src/erlcloud_ec2.erl
Expand Up @@ -2,6 +2,9 @@

-include_lib("xmerl/include/xmerl.hrl").

%% Library initialization.
-export([configure/2, configure/3, new/2, new/3]).

%% EC2 API Functions
-export([
%% Amazon DevPay
Expand Down Expand Up @@ -104,69 +107,26 @@
]).

-define(API_VERSION, "2009-11-30").
-record(ec2_config, {url, host, access_key_id, secret_access_key}).
-type(proplist() :: [{atom(), term()}]).
-type(datetime() :: {{pos_integer(), 1..12, 1..31}, {0..23, 0..59, 0..60}}).
-type(ec2_shutdown_behavior() :: stop | terminate | undefined).
-type(ec2_volume_size() :: 1..1024).
-record(ec2_block_device_mapping, {
device_name::string(),
virtual_name::string(),
snapshot_id::string(),
volume_size::ec2_volume_size(),
delete_on_termination::boolean()
}).
-type(ec2_block_device_mapping() :: #ec2_block_device_mapping{}).
-record(ec2_instance_spec, {
image_id::string(),
min_count=1::pos_integer(),
max_count=1::pos_integer(),
key_name::string(),
group_set::[string()],
user_data::binary(),
instance_type::string(),
availability_zone::string(),
kernel_id::string(),
ramdisk_id::string(),
block_device_mapping::[ec2_block_device_mapping()],
monitoring_enabled=false::boolean(),
subnet_id::string(),
disable_api_termination=false::boolean(),
instance_initiated_shutdown_behavior::ec2_shutdown_behavior()
}).
-record(ec2_image_spec, {
image_location::string(),
name::string(),
description::string(),
architecture::string(),
kernel_id::string(),
ramdisk_id::string(),
root_device_name::string(),
block_device_mapping::[ec2_block_device_mapping()]
}).
-record(ec2_spot_instance_request, {
spot_price::string(),
instance_count=1::pos_integer(),
type=one_time::one_time|persistent,
valid_from::datetime(),
valid_until::datetime(),
launch_group::string(),
availability_zone_group::string(),
launch_specification::#ec2_instance_spec{}
}).
-record(ec2_ingress_spec, {
ip_protocol::tcp|udp|icmp,
from_port::-1 | 0..65535,
to_port::-1 | 0..65535,
source_security_group_owner_id::string(),
source_security_group_name::string(),
cidr_ip::string()
}).
-type(ec2_config() :: #ec2_config{}).
-type(ec2_image_spec() :: #ec2_image_spec{}).
-type(ec2_instance_spec() :: #ec2_instance_spec{}).
-type(ec2_ingress_spec() :: #ec2_ingress_spec{}).
-type(ec2_spot_instance_request() :: #ec2_spot_instance_request{}).
-include("erlcloud_ec2.hrl").

-spec(new/2 :: (string(), string()) -> ec2_config()).
new(AccessKeyID, SecretAccessKey) ->
#ec2_config{access_key_id=AccessKeyID, secret_access_key=SecretAccessKey}.

-spec(new/3 :: (string(), string(), string()) -> ec2_config()).
new(AccessKeyID, SecretAccessKey, Host) ->
#ec2_config{access_key_id=AccessKeyID, secret_access_key=SecretAccessKey,
host=Host}.

-spec(configure/2 :: (string(), string()) -> ok).
configure(AccessKeyID, SecretAccessKey) ->
put(ec2_config, new(AccessKeyID, SecretAccessKey)),
ok.

-spec(configure/3 :: (string(), string(), string()) -> ok).
configure(AccessKeyID, SecretAccessKey, Host) ->
put(ec2_config, new(AccessKeyID, SecretAccessKey, Host)),
ok.

-spec(allocate_address/0 :: () -> string()).
allocate_address() -> allocate_address(default_config()).
Expand Down Expand Up @@ -1471,8 +1431,10 @@ ec2_query(Config, Action, Params) ->

Query = [QueryToSign, "&Signature=", url_encode(Signature)],

URL = lists:flatten(["https://", Config#ec2_config.host, "/"]),

case http:request(post,
{Config#ec2_config.url, [], "application/x-www-form-urlencoded",
{URL, [], "application/x-www-form-urlencoded",
list_to_binary(Query)},
[], []) of
{ok, {{_HTTPVer, 200, _StatusLine}, _Headers, Body}} ->
Expand All @@ -1486,8 +1448,7 @@ ec2_query(Config, Action, Params) ->
default_config() ->
case get(ec2_config) of
undefined ->
#ec2_config{url="https://ec2.amazonaws.com/",
host="ec2.amazonaws.com",
#ec2_config{host="ec2.amazonaws.com",
access_key_id=get(aws_access_key_id),
secret_access_key=get(aws_secret_access_key)};
Config ->
Expand Down

0 comments on commit e22cce1

Please sign in to comment.