simple_aws 0.0.1a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/.travis.yml +8 -0
- data/Gemfile +12 -0
- data/README.md +73 -0
- data/Rakefile +9 -0
- data/lib/aws/api.rb +82 -0
- data/lib/aws/call_types/action_param.rb +68 -0
- data/lib/aws/core/connection.rb +32 -0
- data/lib/aws/core/request.rb +133 -0
- data/lib/aws/core/response.rb +231 -0
- data/lib/aws/core/util.rb +32 -0
- data/lib/aws/ec2.rb +22 -0
- data/lib/aws/elb.rb +21 -0
- data/lib/aws/iam.rb +22 -0
- data/samples/ec2.rb +41 -0
- data/samples/elb.rb +26 -0
- data/samples/iam.rb +30 -0
- data/simple_aws.gemspec +21 -0
- data/test/aws/api_test.rb +101 -0
- data/test/aws/call_types/action_param_test.rb +52 -0
- data/test/aws/core/connection_test.rb +48 -0
- data/test/aws/core/request_test.rb +86 -0
- data/test/aws/core/response_test.rb +318 -0
- data/test/aws/ec2_test.rb +36 -0
- data/test/aws/elb_test.rb +36 -0
- data/test/aws/iam_test.rb +36 -0
- data/test/test_helper.rb +17 -0
- metadata +103 -0
@@ -0,0 +1,318 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'aws/core/response'
|
3
|
+
|
4
|
+
describe AWS::Response do
|
5
|
+
|
6
|
+
describe "errors" do
|
7
|
+
|
8
|
+
before do
|
9
|
+
@error_response = {}
|
10
|
+
@http_response = stub
|
11
|
+
@http_response.stubs(:success?).returns(false)
|
12
|
+
@http_response.stubs(:code).returns(401)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "raises if the response is not a success" do
|
16
|
+
@error_response = {
|
17
|
+
"Response" => {
|
18
|
+
"Errors" => {
|
19
|
+
"Error" => {"Code" => "AuthFailure",
|
20
|
+
"Message" => "Message about failing to authenticate"
|
21
|
+
}}}
|
22
|
+
}
|
23
|
+
@http_response.stubs(:parsed_response).returns(@error_response)
|
24
|
+
|
25
|
+
error =
|
26
|
+
lambda {
|
27
|
+
AWS::Response.new @http_response
|
28
|
+
}.must_raise AWS::UnsuccessfulResponse
|
29
|
+
|
30
|
+
error.code.must_equal 401
|
31
|
+
error.error_type.must_equal "AuthFailure"
|
32
|
+
error.error_message.must_equal "Message about failing to authenticate"
|
33
|
+
|
34
|
+
error.message.must_equal "AuthFailure (401): Message about failing to authenticate"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "handles ErrorResponse objects" do
|
38
|
+
@error_response = {
|
39
|
+
"ErrorResponse" => {
|
40
|
+
"Error" => {"Code" => "AuthFailure",
|
41
|
+
"Message" => "Message about failing to authenticate"
|
42
|
+
}}
|
43
|
+
}
|
44
|
+
@http_response.stubs(:parsed_response).returns(@error_response)
|
45
|
+
|
46
|
+
error =
|
47
|
+
lambda {
|
48
|
+
AWS::Response.new @http_response
|
49
|
+
}.must_raise AWS::UnsuccessfulResponse
|
50
|
+
|
51
|
+
error.code.must_equal 401
|
52
|
+
error.error_type.must_equal "AuthFailure"
|
53
|
+
error.error_message.must_equal "Message about failing to authenticate"
|
54
|
+
|
55
|
+
error.message.must_equal "AuthFailure (401): Message about failing to authenticate"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "raises if it can't parse the error message" do
|
59
|
+
@error_response = { "Erroring" => "This is an error message" }
|
60
|
+
@http_response.stubs(:parsed_response).returns(@error_response)
|
61
|
+
|
62
|
+
error =
|
63
|
+
lambda {
|
64
|
+
AWS::Response.new @http_response
|
65
|
+
}.must_raise AWS::UnknownErrorResponse
|
66
|
+
|
67
|
+
error.message.must_match /Unable to parse error code from/
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "successful response parsing and mapping" do
|
72
|
+
before do
|
73
|
+
@response_hash = {
|
74
|
+
"CommandResponse" => {
|
75
|
+
"xmlns" => "some url",
|
76
|
+
"volumeId" => "v-12345",
|
77
|
+
"domain" => "vpc"
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
@http_response = stub
|
82
|
+
@http_response.stubs(:success?).returns(true)
|
83
|
+
@http_response.stubs(:parsed_response).returns(@response_hash)
|
84
|
+
|
85
|
+
@response = AWS::Response.new @http_response
|
86
|
+
end
|
87
|
+
|
88
|
+
it "saves the parsed response" do
|
89
|
+
@response.body.must_equal @response_hash
|
90
|
+
end
|
91
|
+
|
92
|
+
it "allows querying response body with ruby methods" do
|
93
|
+
@response.volume_id.must_equal "v-12345"
|
94
|
+
@response.domain.must_equal "vpc"
|
95
|
+
|
96
|
+
lambda {
|
97
|
+
@response.unknown_key
|
98
|
+
}.must_raise NoMethodError
|
99
|
+
end
|
100
|
+
|
101
|
+
it "allows accessing the request through Hash format" do
|
102
|
+
@response["volumeId"].must_equal "v-12345"
|
103
|
+
@response["domain"].must_equal "vpc"
|
104
|
+
@response["unknownKey"].must_be_nil
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "deeply nested response/results objects" do
|
110
|
+
before do
|
111
|
+
@response_hash = {
|
112
|
+
"CommandResponse" => {
|
113
|
+
"xmlns" => "some url",
|
114
|
+
"CommandResult" => {
|
115
|
+
"volumeId" => "v-12345",
|
116
|
+
"domain" => "vpc"
|
117
|
+
}
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
121
|
+
@http_response = stub
|
122
|
+
@http_response.stubs(:success?).returns(true)
|
123
|
+
@http_response.stubs(:parsed_response).returns(@response_hash)
|
124
|
+
|
125
|
+
@response = AWS::Response.new @http_response
|
126
|
+
end
|
127
|
+
|
128
|
+
it "starts inside the Result object level" do
|
129
|
+
@response.volume_id.must_equal "v-12345"
|
130
|
+
@response["volumeId"].must_equal "v-12345"
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "nested responses and arrays" do
|
136
|
+
before do
|
137
|
+
@response_hash = {
|
138
|
+
"CommandResponse" => {
|
139
|
+
"xmlns" => "some url",
|
140
|
+
"requestId" => "1234-Request-Id",
|
141
|
+
"nothing" => nil,
|
142
|
+
"simpleNestedObject" => {
|
143
|
+
"name" => "Here's something deeper"
|
144
|
+
},
|
145
|
+
"singleItemResultsSet" => {
|
146
|
+
"item" => {"keyId" => "1234", "domain" => "vpc"},
|
147
|
+
},
|
148
|
+
"multipleItemsSet" => {
|
149
|
+
"item" => [
|
150
|
+
{"keyId" => "1234"},
|
151
|
+
{"keyId" => "5678"},
|
152
|
+
{"keyId" => "9012"}
|
153
|
+
]
|
154
|
+
},
|
155
|
+
"multipleDepthSet" => {
|
156
|
+
"key" => "value",
|
157
|
+
"simpleInnerSet" => {
|
158
|
+
"item" => {"range" => "14"}
|
159
|
+
},
|
160
|
+
"complexInnerSet" => {
|
161
|
+
"item" => [
|
162
|
+
{"range" => "12"},
|
163
|
+
{"range" => "274", "deeperSet" => { "item" => {"hiddenItem" => "42"}}}
|
164
|
+
]
|
165
|
+
}
|
166
|
+
},
|
167
|
+
"withMemberSet" => {
|
168
|
+
"member" => {"keyId" => "4567"}
|
169
|
+
},
|
170
|
+
"UpperCamelKey" => "purple dog"
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
@http_response = stub
|
175
|
+
@http_response.stubs(:success?).returns(true)
|
176
|
+
@http_response.stubs(:parsed_response).returns(@response_hash)
|
177
|
+
|
178
|
+
@response = AWS::Response.new @http_response
|
179
|
+
end
|
180
|
+
|
181
|
+
describe "#keys" do
|
182
|
+
it "lets one introspect the current depth for keys" do
|
183
|
+
@response.simple_nested_object.keys.must_equal ["name"]
|
184
|
+
end
|
185
|
+
|
186
|
+
it "raises if current depth is an array" do
|
187
|
+
lambda {
|
188
|
+
@response.multiple_items_set.keys
|
189
|
+
}.must_raise NoMethodError
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "method calls" do
|
194
|
+
|
195
|
+
it "finds keys who's values are nil" do
|
196
|
+
@response.nothing.must_be_nil
|
197
|
+
end
|
198
|
+
|
199
|
+
it "allows querying multiple objects deep" do
|
200
|
+
@response.simple_nested_object.name.must_equal "Here's something deeper"
|
201
|
+
end
|
202
|
+
|
203
|
+
it "allows querying of a result set with one item, squashing 'item'" do
|
204
|
+
@response.single_item_results_set.length.must_equal 1
|
205
|
+
@response.single_item_results_set.first.key_id.must_equal "1234"
|
206
|
+
@response.single_item_results_set.first.domain.must_equal "vpc"
|
207
|
+
end
|
208
|
+
|
209
|
+
it "allows enumerating through a result set with lots of items" do
|
210
|
+
@response.multiple_items_set.length.must_equal 3
|
211
|
+
@response.multiple_items_set[0].key_id.must_equal "1234"
|
212
|
+
@response.multiple_items_set[1].key_id.must_equal "5678"
|
213
|
+
@response.multiple_items_set[2].key_id.must_equal "9012"
|
214
|
+
end
|
215
|
+
|
216
|
+
it "allows diving into a nested result set" do
|
217
|
+
@response.multiple_depth_set.simple_inner_set.first.range.must_equal "14"
|
218
|
+
@response.multiple_depth_set.complex_inner_set[1].deeper_set[0].hidden_item.must_equal "42"
|
219
|
+
end
|
220
|
+
|
221
|
+
it "also squashes the 'member' tag" do
|
222
|
+
@response.with_member_set[0].key_id.must_equal "4567"
|
223
|
+
end
|
224
|
+
|
225
|
+
it "can work with lowerCamel and UpperCamel when doing method lookup" do
|
226
|
+
@response.upper_camel_key.must_equal "purple dog"
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "hash keys" do
|
232
|
+
|
233
|
+
it "finds keys who's values are nil" do
|
234
|
+
@response["nothing"].must_be_nil
|
235
|
+
end
|
236
|
+
|
237
|
+
it "allows querying multiple objects deep" do
|
238
|
+
@response["simpleNestedObject"]["name"].must_equal "Here's something deeper"
|
239
|
+
end
|
240
|
+
|
241
|
+
it "allows querying of a result set with one item, squashing the 'item' tag" do
|
242
|
+
@response["singleItemResultsSet"].length.must_equal 1
|
243
|
+
@response["singleItemResultsSet"][0]["keyId"].must_equal "1234"
|
244
|
+
@response["singleItemResultsSet"][0]["domain"].must_equal "vpc"
|
245
|
+
end
|
246
|
+
|
247
|
+
it "allows enumerating through a result set with lots of items" do
|
248
|
+
@response["multipleItemsSet"].length.must_equal 3
|
249
|
+
@response["multipleItemsSet"][0]["keyId"].must_equal "1234"
|
250
|
+
@response["multipleItemsSet"][1]["keyId"].must_equal "5678"
|
251
|
+
@response["multipleItemsSet"][2]["keyId"].must_equal "9012"
|
252
|
+
end
|
253
|
+
|
254
|
+
it "allows diving into a nested result set" do
|
255
|
+
@response["multipleDepthSet"]["simpleInnerSet"][0]["range"].must_equal "14"
|
256
|
+
@response["multipleDepthSet"]["complexInnerSet"][1]["deeperSet"][0]["hiddenItem"].must_equal "42"
|
257
|
+
end
|
258
|
+
|
259
|
+
it "also squashes the 'member' tag" do
|
260
|
+
@response["withMemberSet"][0]["keyId"].must_equal "4567"
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
end
|
265
|
+
|
266
|
+
describe "#request_id" do
|
267
|
+
before do
|
268
|
+
@http_response = stub
|
269
|
+
@http_response.stubs(:success?).returns(true)
|
270
|
+
end
|
271
|
+
|
272
|
+
it "finds the top level response id" do
|
273
|
+
response_hash = {
|
274
|
+
"CommandResponse" => {
|
275
|
+
"xmlns" => "some url",
|
276
|
+
"requestId" => "1234-Request-Id"
|
277
|
+
}
|
278
|
+
}
|
279
|
+
@http_response.stubs(:parsed_response).returns(response_hash)
|
280
|
+
|
281
|
+
response = AWS::Response.new @http_response
|
282
|
+
|
283
|
+
response.request_id.must_equal "1234-Request-Id"
|
284
|
+
end
|
285
|
+
|
286
|
+
it "finds response id nested" do
|
287
|
+
response_hash = {
|
288
|
+
"CommandResponse" => {
|
289
|
+
"CommandResult" => {
|
290
|
+
},
|
291
|
+
"ResponseMetadata" => {
|
292
|
+
"RequestId" => "1234-Request-Id"
|
293
|
+
}
|
294
|
+
}
|
295
|
+
}
|
296
|
+
@http_response.stubs(:parsed_response).returns(response_hash)
|
297
|
+
|
298
|
+
response = AWS::Response.new @http_response
|
299
|
+
|
300
|
+
response.request_id.must_equal "1234-Request-Id"
|
301
|
+
end
|
302
|
+
|
303
|
+
it "returns nil if no request id found" do
|
304
|
+
response_hash = {
|
305
|
+
"CommandResponse" => {
|
306
|
+
"CommandResult" => {
|
307
|
+
}
|
308
|
+
}
|
309
|
+
}
|
310
|
+
@http_response.stubs(:parsed_response).returns(response_hash)
|
311
|
+
|
312
|
+
response = AWS::Response.new @http_response
|
313
|
+
|
314
|
+
response.request_id.must_be_nil
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'aws/ec2'
|
3
|
+
|
4
|
+
describe AWS::EC2 do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@api = AWS::EC2.new "key", "secret"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "points to ec2" do
|
11
|
+
@api.uri.must_equal "https://ec2.amazonaws.com"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "works with the current version" do
|
15
|
+
@api.version.must_equal "2011-11-01"
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "API calls" do
|
19
|
+
|
20
|
+
it "builds and signs calls with ActionParam rules" do
|
21
|
+
AWS::Connection.any_instance.expects(:call).with do |request|
|
22
|
+
params = request.params
|
23
|
+
params.wont_be_nil
|
24
|
+
|
25
|
+
params["Action"].must_equal "DescribeInstances"
|
26
|
+
params["Signature"].wont_be_nil
|
27
|
+
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
obj = AWS::EC2.new "key", "secret"
|
32
|
+
obj.describe_instances
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'aws/elb'
|
3
|
+
|
4
|
+
describe AWS::ELB do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@api = AWS::ELB.new "key", "secret"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "points to elb" do
|
11
|
+
@api.uri.must_equal "https://elasticloadbalancing.amazonaws.com"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "works with the current version" do
|
15
|
+
@api.version.must_equal "2011-11-15"
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "API calls" do
|
19
|
+
|
20
|
+
it "builds and signs calls with ActionParam rules" do
|
21
|
+
AWS::Connection.any_instance.expects(:call).with do |request|
|
22
|
+
params = request.params
|
23
|
+
params.wont_be_nil
|
24
|
+
|
25
|
+
params["Action"].must_equal "DescribeLoadBalancers"
|
26
|
+
params["Signature"].wont_be_nil
|
27
|
+
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
obj = AWS::ELB.new "key", "secret"
|
32
|
+
obj.describe_load_balancers
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'aws/iam'
|
3
|
+
|
4
|
+
describe AWS::IAM do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@api = AWS::IAM.new "key", "secret"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "points to iam" do
|
11
|
+
@api.uri.must_equal "https://iam.amazonaws.com"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "works with the current version" do
|
15
|
+
@api.version.must_equal "2010-05-08"
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "API calls" do
|
19
|
+
|
20
|
+
it "builds and signs calls with ActionParam rules" do
|
21
|
+
AWS::Connection.any_instance.expects(:call).with do |request|
|
22
|
+
params = request.params
|
23
|
+
params.wont_be_nil
|
24
|
+
|
25
|
+
params["Action"].must_equal "GetGroup"
|
26
|
+
params["Signature"].wont_be_nil
|
27
|
+
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
obj = AWS::IAM.new "key", "secret"
|
32
|
+
obj.get_group
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple_aws
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1a
|
5
|
+
prerelease: 5
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jason Roelofs
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ox
|
16
|
+
requirement: &70336671153960 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70336671153960
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: httparty
|
27
|
+
requirement: &70336671153520 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70336671153520
|
36
|
+
description: The simplest and easiest to use and maintain AWS communication library
|
37
|
+
email:
|
38
|
+
- jameskilton@gmail.com
|
39
|
+
executables: []
|
40
|
+
extensions: []
|
41
|
+
extra_rdoc_files: []
|
42
|
+
files:
|
43
|
+
- .gitignore
|
44
|
+
- .travis.yml
|
45
|
+
- Gemfile
|
46
|
+
- README.md
|
47
|
+
- Rakefile
|
48
|
+
- lib/aws/api.rb
|
49
|
+
- lib/aws/call_types/action_param.rb
|
50
|
+
- lib/aws/core/connection.rb
|
51
|
+
- lib/aws/core/request.rb
|
52
|
+
- lib/aws/core/response.rb
|
53
|
+
- lib/aws/core/util.rb
|
54
|
+
- lib/aws/ec2.rb
|
55
|
+
- lib/aws/elb.rb
|
56
|
+
- lib/aws/iam.rb
|
57
|
+
- samples/ec2.rb
|
58
|
+
- samples/elb.rb
|
59
|
+
- samples/iam.rb
|
60
|
+
- simple_aws.gemspec
|
61
|
+
- test/aws/api_test.rb
|
62
|
+
- test/aws/call_types/action_param_test.rb
|
63
|
+
- test/aws/core/connection_test.rb
|
64
|
+
- test/aws/core/request_test.rb
|
65
|
+
- test/aws/core/response_test.rb
|
66
|
+
- test/aws/ec2_test.rb
|
67
|
+
- test/aws/elb_test.rb
|
68
|
+
- test/aws/iam_test.rb
|
69
|
+
- test/test_helper.rb
|
70
|
+
homepage:
|
71
|
+
licenses: []
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>'
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 1.3.1
|
88
|
+
requirements: []
|
89
|
+
rubyforge_project:
|
90
|
+
rubygems_version: 1.8.10
|
91
|
+
signing_key:
|
92
|
+
specification_version: 3
|
93
|
+
summary: The simplest and easiest to use and maintain AWS communication library
|
94
|
+
test_files:
|
95
|
+
- test/aws/api_test.rb
|
96
|
+
- test/aws/call_types/action_param_test.rb
|
97
|
+
- test/aws/core/connection_test.rb
|
98
|
+
- test/aws/core/request_test.rb
|
99
|
+
- test/aws/core/response_test.rb
|
100
|
+
- test/aws/ec2_test.rb
|
101
|
+
- test/aws/elb_test.rb
|
102
|
+
- test/aws/iam_test.rb
|
103
|
+
- test/test_helper.rb
|