bguthrie-awsymandias 0.2.1 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.specification +57 -0
- data/README.rdoc +25 -21
- data/Rakefile +20 -4
- data/VERSION +1 -1
- data/awsymandias.gemspec +37 -12
- data/lib/awsymandias.rb +36 -331
- data/lib/awsymandias/addons/right_elb_interface.rb +375 -0
- data/lib/awsymandias/ec2.rb +49 -0
- data/lib/awsymandias/ec2/application_stack.rb +261 -0
- data/lib/awsymandias/extensions/class_extension.rb +18 -0
- data/lib/awsymandias/extensions/net_http_extension.rb +9 -0
- data/lib/awsymandias/instance.rb +149 -0
- data/lib/awsymandias/load_balancer.rb +157 -0
- data/lib/awsymandias/right_aws.rb +73 -0
- data/lib/awsymandias/right_elb.rb +16 -0
- data/lib/awsymandias/simple_db.rb +46 -0
- data/lib/awsymandias/snapshot.rb +33 -0
- data/lib/awsymandias/stack_definition.rb +60 -0
- data/lib/awsymandias/volume.rb +70 -0
- data/spec/integration/instance_spec.rb +37 -0
- data/spec/unit/addons/right_elb_interface_spec.rb +45 -0
- data/spec/unit/awsymandias_spec.rb +61 -0
- data/spec/unit/ec2/application_stack_spec.rb +634 -0
- data/spec/unit/instance_spec.rb +365 -0
- data/spec/unit/load_balancer_spec.rb +250 -0
- data/spec/unit/right_aws_spec.rb +90 -0
- data/spec/unit/simple_db_spec.rb +63 -0
- data/spec/unit/snapshot_spec.rb +39 -0
- data/spec/unit/stack_definition_spec.rb +113 -0
- data/tags +368 -0
- metadata +39 -13
- data/spec/awsymandias_spec.rb +0 -815
- data/vendor/aws-sdb/LICENSE +0 -19
- data/vendor/aws-sdb/README +0 -1
- data/vendor/aws-sdb/Rakefile +0 -20
- data/vendor/aws-sdb/lib/aws_sdb.rb +0 -3
- data/vendor/aws-sdb/lib/aws_sdb/error.rb +0 -42
- data/vendor/aws-sdb/lib/aws_sdb/service.rb +0 -191
- data/vendor/aws-sdb/spec/aws_sdb/service_spec.rb +0 -183
- data/vendor/aws-sdb/spec/spec_helper.rb +0 -4
data/vendor/aws-sdb/LICENSE
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
Copyright (c) 2007, 2008 Tim Dysinger
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
of this software and associated documentation files (the "Software"), to deal
|
5
|
-
in the Software without restriction, including without limitation the rights
|
6
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
copies of the Software, and to permit persons to whom the Software is
|
8
|
-
furnished to do so, subject to the following conditions:
|
9
|
-
|
10
|
-
The above copyright notice and this permission notice shall be included in
|
11
|
-
all copies or substantial portions of the Software.
|
12
|
-
|
13
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
THE SOFTWARE.
|
data/vendor/aws-sdb/README
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
Amazon SDB API
|
data/vendor/aws-sdb/Rakefile
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'spec/rake/spectask'
|
3
|
-
require 'rake/gempackagetask'
|
4
|
-
|
5
|
-
Spec::Rake::SpecTask.new
|
6
|
-
|
7
|
-
gem_spec = eval(IO.read(File.join(File.dirname(__FILE__), "aws-sdb.gemspec")))
|
8
|
-
|
9
|
-
desc "Open an irb session preloaded with this library"
|
10
|
-
task :console do
|
11
|
-
sh "irb -rubygems -I lib -r aws_sdb.rb"
|
12
|
-
end
|
13
|
-
|
14
|
-
Rake::GemPackageTask.new(gem_spec) do |pkg|
|
15
|
-
pkg.gem_spec = gem_spec
|
16
|
-
end
|
17
|
-
|
18
|
-
task :install => [:package] do
|
19
|
-
sh %{sudo gem install pkg/#{gem_spec.name}-#{gem_spec.version}}
|
20
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module AwsSdb
|
2
|
-
|
3
|
-
class Error < RuntimeError ; end
|
4
|
-
|
5
|
-
class RequestError < Error
|
6
|
-
attr_reader :request_id
|
7
|
-
|
8
|
-
def initialize(message, request_id=nil)
|
9
|
-
super(message)
|
10
|
-
@request_id = request_id
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class InvalidDomainNameError < RequestError ; end
|
15
|
-
class InvalidParameterValueError < RequestError ; end
|
16
|
-
class InvalidNextTokenError < RequestError ; end
|
17
|
-
class InvalidNumberPredicatesError < RequestError ; end
|
18
|
-
class InvalidNumberValueTestsError < RequestError ; end
|
19
|
-
class InvalidQueryExpressionError < RequestError ; end
|
20
|
-
class MissingParameterError < RequestError ; end
|
21
|
-
class NoSuchDomainError < RequestError ; end
|
22
|
-
class NumberDomainsExceededError < RequestError ; end
|
23
|
-
class NumberDomainAttributesExceededError < RequestError ; end
|
24
|
-
class NumberDomainBytesExceededError < RequestError ; end
|
25
|
-
class NumberItemAttributesExceededError < RequestError ; end
|
26
|
-
class RequestTimeoutError < RequestError ; end
|
27
|
-
|
28
|
-
class FeatureDeprecatedError < RequestError ; end
|
29
|
-
|
30
|
-
class ConnectionError < Error
|
31
|
-
attr_reader :response
|
32
|
-
|
33
|
-
def initialize(response)
|
34
|
-
super(
|
35
|
-
"#{response.code} \
|
36
|
-
#{response.message if response.respond_to?(:message)}"
|
37
|
-
)
|
38
|
-
@response = response
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
@@ -1,191 +0,0 @@
|
|
1
|
-
require 'logger'
|
2
|
-
require 'time'
|
3
|
-
require 'cgi'
|
4
|
-
require 'uri'
|
5
|
-
require 'net/http'
|
6
|
-
require 'base64'
|
7
|
-
require 'openssl'
|
8
|
-
require 'rexml/document'
|
9
|
-
require 'rexml/xpath'
|
10
|
-
|
11
|
-
module AwsSdb
|
12
|
-
|
13
|
-
class Service
|
14
|
-
def initialize(options={})
|
15
|
-
@access_key_id = options[:access_key_id] || ENV['AMAZON_ACCESS_KEY_ID']
|
16
|
-
@secret_access_key = options[:secret_access_key] || ENV['AMAZON_SECRET_ACCESS_KEY']
|
17
|
-
@base_url = options[:url] || 'http://sdb.amazonaws.com'
|
18
|
-
@logger = options[:logger] || Logger.new("aws_sdb.log")
|
19
|
-
end
|
20
|
-
|
21
|
-
def list_domains(max = nil, token = nil)
|
22
|
-
params = { 'Action' => 'ListDomains' }
|
23
|
-
params['NextToken'] =
|
24
|
-
token unless token.nil? || token.empty?
|
25
|
-
params['MaxNumberOfDomains'] =
|
26
|
-
max.to_s unless max.nil? || max.to_i == 0
|
27
|
-
doc = call(:get, params)
|
28
|
-
results = []
|
29
|
-
REXML::XPath.each(doc, '//DomainName/text()') do |domain|
|
30
|
-
results << domain.to_s
|
31
|
-
end
|
32
|
-
return results, REXML::XPath.first(doc, '//NextToken/text()').to_s
|
33
|
-
end
|
34
|
-
|
35
|
-
def create_domain(domain)
|
36
|
-
call(:post, { 'Action' => 'CreateDomain', 'DomainName'=> domain.to_s })
|
37
|
-
nil
|
38
|
-
end
|
39
|
-
|
40
|
-
def delete_domain(domain)
|
41
|
-
call(
|
42
|
-
:delete,
|
43
|
-
{ 'Action' => 'DeleteDomain', 'DomainName' => domain.to_s }
|
44
|
-
)
|
45
|
-
nil
|
46
|
-
end
|
47
|
-
# <QueryWithAttributesResult><Item><Name>in-c2ffrw</Name><Attribute><Name>code</Name><Value>in-c2ffrw</Value></Attribute><Attribute><Name>date_created</Name><Value>2008-10-31</Value></Attribute></Item><Item>
|
48
|
-
def query_with_attributes(domain, query, max = nil, token = nil)
|
49
|
-
params = {
|
50
|
-
'Action' => 'QueryWithAttributes',
|
51
|
-
'QueryExpression' => query,
|
52
|
-
'DomainName' => domain.to_s
|
53
|
-
}
|
54
|
-
params['NextToken'] =
|
55
|
-
token unless token.nil? || token.empty?
|
56
|
-
params['MaxNumberOfItems'] =
|
57
|
-
max.to_s unless max.nil? || max.to_i == 0
|
58
|
-
|
59
|
-
doc = call(:get, params)
|
60
|
-
results = []
|
61
|
-
REXML::XPath.each(doc, "//Item") do |item|
|
62
|
-
name = REXML::XPath.first(item, './Name/text()').to_s
|
63
|
-
|
64
|
-
|
65
|
-
attributes = {'Name' => name}
|
66
|
-
REXML::XPath.each(item, "./Attribute") do |attr|
|
67
|
-
key = REXML::XPath.first(attr, './Name/text()').to_s
|
68
|
-
value = REXML::XPath.first(attr, './Value/text()').to_s
|
69
|
-
( attributes[key] ||= [] ) << value
|
70
|
-
end
|
71
|
-
results << attributes
|
72
|
-
end
|
73
|
-
return results, REXML::XPath.first(doc, '//NextToken/text()').to_s
|
74
|
-
end
|
75
|
-
|
76
|
-
# <QueryResult><ItemName>in-c2ffrw</ItemName><ItemName>in-72yagt</ItemName><ItemName>in-52j8gj</ItemName>
|
77
|
-
def query(domain, query, max = nil, token = nil)
|
78
|
-
params = {
|
79
|
-
'Action' => 'Query',
|
80
|
-
'QueryExpression' => query,
|
81
|
-
'DomainName' => domain.to_s
|
82
|
-
}
|
83
|
-
params['NextToken'] =
|
84
|
-
token unless token.nil? || token.empty?
|
85
|
-
params['MaxNumberOfItems'] =
|
86
|
-
max.to_s unless max.nil? || max.to_i == 0
|
87
|
-
|
88
|
-
|
89
|
-
doc = call(:get, params)
|
90
|
-
results = []
|
91
|
-
REXML::XPath.each(doc, '//ItemName/text()') do |item|
|
92
|
-
results << item.to_s
|
93
|
-
end
|
94
|
-
return results, REXML::XPath.first(doc, '//NextToken/text()').to_s
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
def put_attributes(domain, item, attributes, replace = true)
|
99
|
-
params = {
|
100
|
-
'Action' => 'PutAttributes',
|
101
|
-
'DomainName' => domain.to_s,
|
102
|
-
'ItemName' => item.to_s
|
103
|
-
}
|
104
|
-
count = 0
|
105
|
-
attributes.each do | key, values |
|
106
|
-
([]<<values).flatten.each do |value|
|
107
|
-
params["Attribute.#{count}.Name"] = key.to_s
|
108
|
-
params["Attribute.#{count}.Value"] = value.to_s
|
109
|
-
params["Attribute.#{count}.Replace"] = replace
|
110
|
-
count += 1
|
111
|
-
end
|
112
|
-
end
|
113
|
-
call(:put, params)
|
114
|
-
nil
|
115
|
-
end
|
116
|
-
|
117
|
-
def get_attributes(domain, item)
|
118
|
-
doc = call(
|
119
|
-
:get,
|
120
|
-
{
|
121
|
-
'Action' => 'GetAttributes',
|
122
|
-
'DomainName' => domain.to_s,
|
123
|
-
'ItemName' => item.to_s
|
124
|
-
}
|
125
|
-
)
|
126
|
-
attributes = {}
|
127
|
-
REXML::XPath.each(doc, "//Attribute") do |attr|
|
128
|
-
key = REXML::XPath.first(attr, './Name/text()').to_s
|
129
|
-
value = REXML::XPath.first(attr, './Value/text()').to_s
|
130
|
-
( attributes[key] ||= [] ) << value
|
131
|
-
end
|
132
|
-
attributes
|
133
|
-
end
|
134
|
-
|
135
|
-
def delete_attributes(domain, item)
|
136
|
-
call(
|
137
|
-
:delete,
|
138
|
-
{
|
139
|
-
'Action' => 'DeleteAttributes',
|
140
|
-
'DomainName' => domain.to_s,
|
141
|
-
'ItemName' => item.to_s
|
142
|
-
}
|
143
|
-
)
|
144
|
-
nil
|
145
|
-
end
|
146
|
-
|
147
|
-
protected
|
148
|
-
|
149
|
-
def call(method, params)
|
150
|
-
params.merge!( {
|
151
|
-
'Version' => '2007-11-07',
|
152
|
-
'SignatureVersion' => '1',
|
153
|
-
'AWSAccessKeyId' => @access_key_id,
|
154
|
-
'Timestamp' => Time.now.gmtime.iso8601
|
155
|
-
}
|
156
|
-
)
|
157
|
-
data = ''
|
158
|
-
query = []
|
159
|
-
params.keys.sort_by { |k| k.upcase }.each do |key|
|
160
|
-
data << "#{key}#{params[key].to_s}"
|
161
|
-
query << "#{key}=#{CGI::escape(params[key].to_s)}"
|
162
|
-
end
|
163
|
-
digest = OpenSSL::Digest::Digest.new('sha1')
|
164
|
-
hmac = OpenSSL::HMAC.digest(digest, @secret_access_key, data)
|
165
|
-
signature = Base64.encode64(hmac).strip
|
166
|
-
query << "Signature=#{CGI::escape(signature)}"
|
167
|
-
query = query.join('&')
|
168
|
-
url = "#{@base_url}?#{query}"
|
169
|
-
uri = URI.parse(url)
|
170
|
-
@logger.debug("#{url}") if @logger
|
171
|
-
response =
|
172
|
-
Net::HTTP.new(uri.host, uri.port).send_request(method, uri.request_uri)
|
173
|
-
@logger.debug("#{response.code}\n#{response.body}") if @logger
|
174
|
-
raise(ConnectionError.new(response)) unless (200..400).include?(
|
175
|
-
response.code.to_i
|
176
|
-
)
|
177
|
-
doc = REXML::Document.new(response.body)
|
178
|
-
error = doc.get_elements('*/Errors/Error')[0]
|
179
|
-
raise(
|
180
|
-
Module.class_eval(
|
181
|
-
"AwsSdb::#{error.get_elements('Code')[0].text}Error"
|
182
|
-
).new(
|
183
|
-
error.get_elements('Message')[0].text,
|
184
|
-
doc.get_elements('*/RequestID')[0].text
|
185
|
-
)
|
186
|
-
) unless error.nil?
|
187
|
-
doc
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
end
|
@@ -1,183 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
-
|
3
|
-
require 'digest/sha1'
|
4
|
-
require 'net/http'
|
5
|
-
require 'rexml/document'
|
6
|
-
|
7
|
-
require 'rubygems'
|
8
|
-
require 'uuidtools'
|
9
|
-
|
10
|
-
include AwsSdb
|
11
|
-
|
12
|
-
describe Service, "when creating a new domain" do
|
13
|
-
before(:all) do
|
14
|
-
@service = AwsSdb::Service.new
|
15
|
-
@domain = "test-#{UUID.random_create.to_s}"
|
16
|
-
domains = @service.list_domains[0]
|
17
|
-
domains.each do |d|
|
18
|
-
@service.delete_domain(d) if d =~ /^test/
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
after(:all) do
|
23
|
-
@service.delete_domain(@domain)
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should not raise an error if a valid new domain name is given" do
|
27
|
-
lambda {
|
28
|
-
@service.create_domain("test-#{UUID.random_create.to_s}")
|
29
|
-
}.should_not raise_error
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should not raise an error if the domain name already exists" do
|
33
|
-
domain = "test-#{UUID.random_create.to_s}"
|
34
|
-
lambda {
|
35
|
-
@service.create_domain(domain)
|
36
|
-
@service.create_domain(domain)
|
37
|
-
}.should_not raise_error
|
38
|
-
end
|
39
|
-
|
40
|
-
it "should raise an error if an a nil or '' domain name is given" do
|
41
|
-
lambda {
|
42
|
-
@service.create_domain('')
|
43
|
-
}.should raise_error(InvalidParameterValueError)
|
44
|
-
lambda {
|
45
|
-
@service.create_domain(nil)
|
46
|
-
}.should raise_error(InvalidParameterValueError)
|
47
|
-
lambda {
|
48
|
-
@service.create_domain(' ')
|
49
|
-
}.should raise_error(InvalidParameterValueError)
|
50
|
-
end
|
51
|
-
|
52
|
-
it "should raise an error if the domain name length is < 3 or > 255" do
|
53
|
-
lambda {
|
54
|
-
@service.create_domain('xx')
|
55
|
-
}.should raise_error(InvalidParameterValueError)
|
56
|
-
lambda {
|
57
|
-
@service.create_domain('x'*256)
|
58
|
-
}.should raise_error(InvalidParameterValueError)
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should only accept domain names with a-z, A-Z, 0-9, '_', '-', and '.' " do
|
62
|
-
lambda {
|
63
|
-
@service.create_domain('@$^*()')
|
64
|
-
}.should raise_error(InvalidParameterValueError)
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should only accept a maximum of 100 domain names"
|
68
|
-
|
69
|
-
it "should not have to call amazon to determine domain name correctness"
|
70
|
-
end
|
71
|
-
|
72
|
-
describe Service, "when listing domains" do
|
73
|
-
before(:all) do
|
74
|
-
@service = AwsSdb::Service.new
|
75
|
-
@domain = "test-#{UUID.random_create.to_s}"
|
76
|
-
@service.list_domains[0].each do |d|
|
77
|
-
@service.delete_domain(d) if d =~ /^test/
|
78
|
-
end
|
79
|
-
@service.create_domain(@domain)
|
80
|
-
end
|
81
|
-
|
82
|
-
after(:all) do
|
83
|
-
@service.delete_domain(@domain)
|
84
|
-
end
|
85
|
-
|
86
|
-
it "should return a complete list" do
|
87
|
-
result = nil
|
88
|
-
lambda { result = @service.list_domains[0] }.should_not raise_error
|
89
|
-
result.should_not be_nil
|
90
|
-
result.should_not be_empty
|
91
|
-
result.include?(@domain).should == true
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
describe Service, "when deleting domains" do
|
96
|
-
before(:all) do
|
97
|
-
@service = AwsSdb::Service.new
|
98
|
-
@domain = "test-#{UUID.random_create.to_s}"
|
99
|
-
@service.list_domains[0].each do |d|
|
100
|
-
@service.delete_domain(d) if d =~ /^test/
|
101
|
-
end
|
102
|
-
@service.create_domain(@domain)
|
103
|
-
end
|
104
|
-
|
105
|
-
after do
|
106
|
-
@service.delete_domain(@domain)
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should be able to delete an existing domain" do
|
110
|
-
lambda { @service.delete_domain(@domain) }.should_not raise_error
|
111
|
-
end
|
112
|
-
|
113
|
-
it "should not raise an error trying to delete a non-existing domain" do
|
114
|
-
lambda {
|
115
|
-
@service.delete_domain(UUID.random_create.to_s)
|
116
|
-
}.should_not raise_error
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
describe Service, "when managing items" do
|
121
|
-
before(:all) do
|
122
|
-
@service = AwsSdb::Service.new
|
123
|
-
@domain = "test-#{UUID.random_create.to_s}"
|
124
|
-
@service.list_domains[0].each do |d|
|
125
|
-
@service.delete_domain(d) if d =~ /^test/
|
126
|
-
end
|
127
|
-
@service.create_domain(@domain)
|
128
|
-
@item = "test-#{UUID.random_create.to_s}"
|
129
|
-
@attributes = {
|
130
|
-
:question => 'What is the answer?',
|
131
|
-
:answer => [ true, 'testing123', 4.2, 42, 420 ]
|
132
|
-
}
|
133
|
-
end
|
134
|
-
|
135
|
-
after(:all) do
|
136
|
-
@service.delete_domain(@domain)
|
137
|
-
end
|
138
|
-
|
139
|
-
it "should be able to put attributes" do
|
140
|
-
lambda {
|
141
|
-
@service.put_attributes(@domain, @item, @attributes)
|
142
|
-
}.should_not raise_error
|
143
|
-
end
|
144
|
-
|
145
|
-
it "should be able to get attributes" do
|
146
|
-
result = nil
|
147
|
-
lambda {
|
148
|
-
result = @service.get_attributes(@domain, @item)
|
149
|
-
}.should_not raise_error
|
150
|
-
result.should_not be_nil
|
151
|
-
result.should_not be_empty
|
152
|
-
result.has_key?('answer').should == true
|
153
|
-
@attributes[:answer].each do |v|
|
154
|
-
result['answer'].include?(v.to_s).should == true
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
it "should be able to query" do
|
159
|
-
result = nil
|
160
|
-
lambda {
|
161
|
-
result = @service.query(@domain, "[ 'answer' = '42' ]")[0]
|
162
|
-
}.should_not raise_error
|
163
|
-
result.should_not be_nil
|
164
|
-
result.should_not be_empty
|
165
|
-
result.should_not be_nil
|
166
|
-
result.include?(@item).should == true
|
167
|
-
end
|
168
|
-
|
169
|
-
it "should be able to query with attributes"
|
170
|
-
|
171
|
-
it "should be able to delete attributes" do
|
172
|
-
lambda {
|
173
|
-
@service.delete_attributes(@domain, @item)
|
174
|
-
}.should_not raise_error
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
# TODO Pull the specs from the amazon docs and write more rspec
|
179
|
-
# 100 attributes per each call
|
180
|
-
# 256 total attribute name-value pairs per item
|
181
|
-
# 250 million attributes per domain
|
182
|
-
# 10 GB of total user data storage per domain
|
183
|
-
# ...etc...
|