swirl 1.6.2 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -54,6 +54,9 @@ nifty trick we use in (Rack)[http://github.com/rack/rack]
54
54
  Use
55
55
  ---
56
56
 
57
+ require 'rubygems' # if you're using rubygems
58
+ require 'swirl/aws'
59
+
57
60
  ec2 = Swirl::EC2.new
58
61
 
59
62
  # Describe all instances
data/lib/swirl.rb CHANGED
@@ -1 +1,2 @@
1
1
  require 'swirl/ec2'
2
+ require 'swirl/aws'
data/lib/swirl/aws.rb ADDED
@@ -0,0 +1,154 @@
1
+ require 'cgi'
2
+ require 'base64'
3
+ require 'net/https'
4
+
5
+ require 'crack/xml'
6
+ require 'hmac-sha2'
7
+
8
+ require 'swirl/helpers'
9
+
10
+
11
+ module Swirl
12
+
13
+ ## Errors
14
+ class InvalidRequest < StandardError ; end
15
+
16
+
17
+ class AWS
18
+ include Helpers::Compactor
19
+ include Helpers::Expander
20
+
21
+ @services = {}
22
+
23
+ def self.services
24
+ # This must be modified using `service`
25
+ @services.dup
26
+ end
27
+
28
+ def self.service(name, url, version)
29
+ @services[name] = { :url => url, :version => version }
30
+ end
31
+
32
+ # Default Services
33
+ service :ec2, "https://ec2.amazonaws.com", "2010-11-15"
34
+
35
+
36
+ def initialize(*args)
37
+ opts = args.last.is_a?(Hash) ? args.pop : Hash.new
38
+ name = args.shift
39
+
40
+ service = self.class.services[name] || {}
41
+ opts = service.merge(opts)
42
+
43
+ @url = opts[:url] ||
44
+ raise(ArgumentError, "No url given")
45
+
46
+ # Convert this here for future reference
47
+ @url = URI(@url)
48
+
49
+ @version = opts[:version] ||
50
+ raise(ArgumentError, "No version given")
51
+
52
+ @aws_access_key_id = \
53
+ ENV["AWS_ACCESS_KEY_ID"] ||
54
+ opts[:aws_access_key_id] ||
55
+ raise(ArgumentError, "No aws_access_key_id given")
56
+
57
+ @aws_secret_access_key = \
58
+ ENV["AWS_SECRET_ACCESS_KEY"] ||
59
+ opts[:aws_secret_access_key] ||
60
+ raise(ArgumentError, "No aws_secret_access_key given")
61
+
62
+ @hmac = HMAC::SHA256.new(@aws_secret_access_key)
63
+ end
64
+
65
+ def escape(value)
66
+ CGI.escape(value).gsub(/\+/, "%20")
67
+ end
68
+
69
+ def compile_sorted_form_data(query)
70
+ valid = query.reject {|_, v| v.nil? }
71
+ valid.sort.map {|k,v| [k, escape(v)] * "=" } * "&"
72
+ end
73
+
74
+ def compile_signature(method, body)
75
+ string_to_sign = [method, @url.host, "/", body] * "\n"
76
+ hmac = @hmac.update(string_to_sign)
77
+ encoded_sig = Base64.encode64(hmac.digest).chomp
78
+ escape(encoded_sig)
79
+ end
80
+
81
+ ##
82
+ # Execute an EC2 command, expand the input,
83
+ # and compact the output
84
+ #
85
+ # Examples:
86
+ # ec2.call("DescribeInstances")
87
+ # ec2.call("TerminateInstances", "InstanceId" => ["i-1234", "i-993j"]
88
+ #
89
+ def call(action, query={}, &blk)
90
+ call!(action, expand(query)) do |code, data|
91
+ case code
92
+ when 200
93
+ response = compact(data)
94
+ when 400...500
95
+ messages = Array(data["Response"]["Errors"]).map {|_, e| e["Message"] }
96
+ raise InvalidRequest, messages.join(",")
97
+ else
98
+ msg = "unexpected response #{code} -> #{data.inspect}"
99
+ raise InvalidRequest, msg
100
+ end
101
+
102
+ if blk
103
+ blk.call(response)
104
+ else
105
+ response
106
+ end
107
+ end
108
+ end
109
+
110
+ def call!(action, query={}, &blk)
111
+ # Hard coding this here until otherwise needed
112
+ method = "POST"
113
+
114
+ query["Action"] = action
115
+ query["AWSAccessKeyId"] = @aws_access_key_id
116
+ query["SignatureMethod"] = "HmacSHA256"
117
+ query["SignatureVersion"] = "2"
118
+ query["Timestamp"] = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
119
+ query["Version"] = @version
120
+
121
+ body = compile_sorted_form_data(query)
122
+ body += "&" + ["Signature", compile_signature(method, body)].join("=")
123
+
124
+ post(body) do |code, xml|
125
+ if ENV["SWIRL_LOG"]
126
+ puts response.body
127
+ end
128
+
129
+ data = Crack::XML.parse(xml)
130
+ blk.call(code, data)
131
+ end
132
+ end
133
+
134
+ def post(body, &blk)
135
+ headers = { "Content-Type" => "application/x-www-form-urlencoded" }
136
+
137
+ http = Net::HTTP.new(@url.host, @url.port)
138
+ http.use_ssl = true
139
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
140
+
141
+ request = Net::HTTP::Post.new(@url.request_uri, headers)
142
+ request.body = body
143
+
144
+ response = http.request(request)
145
+ blk.call(response.code.to_i, response.body)
146
+ end
147
+
148
+ def inspect
149
+ "<#{self.class.name} version: #{@version} url: #{@url} aws_access_key_id: #{@aws_access_key_id}>"
150
+ end
151
+
152
+ end
153
+
154
+ end
data/lib/swirl/ec2.rb CHANGED
@@ -1,123 +1,15 @@
1
- require 'cgi'
2
- require 'base64'
3
- require 'net/https'
1
+ require 'swirl/aws'
4
2
 
5
- require 'crack/xml'
6
- require 'hmac-sha2'
7
-
8
- require 'swirl/helpers'
3
+ $stderr.puts "WARNING: Requiring 'swirl' or 'swirl/ec2' will be deprecated. Require 'swirl/aws' instead."
9
4
 
10
5
  module Swirl
11
6
 
12
- ## Errors
13
- class InvalidRequest < StandardError ; end
14
-
15
-
7
+ # Compat
16
8
  class EC2
17
- include Helpers::Compactor
18
- include Helpers::Expander
19
-
20
-
21
- def initialize(options)
22
- @aws_access_key_id =
23
- options[:aws_access_key_id] ||
24
- (raise ArgumentError, "no aws_access_key_id provided")
25
- @aws_secret_access_key =
26
- options[:aws_secret_access_key] ||
27
- (raise ArgumentError, "no aws_secret_access_key provided")
28
-
29
- @hmac = HMAC::SHA256.new(@aws_secret_access_key)
30
- @version = options[:version] || "2009-11-30"
31
- @url = URI(options[:url] || "https://ec2.amazonaws.com")
32
- end
33
-
34
- def escape(value)
35
- CGI.escape(value).gsub(/\+/, "%20")
36
- end
37
-
38
- def compile_sorted_form_data(query)
39
- valid = query.reject {|_, v| v.nil? }
40
- valid.sort.map {|k,v| [k, escape(v)] * "=" } * "&"
41
- end
42
-
43
- def compile_signature(method, body)
44
- string_to_sign = [method, @url.host, "/", body] * "\n"
45
- hmac = @hmac.update(string_to_sign)
46
- encoded_sig = Base64.encode64(hmac.digest).chomp
47
- escape(encoded_sig)
48
- end
49
-
50
- ##
51
- # Execute an EC2 command, expand the input,
52
- # and compact the output
53
- #
54
- # Examples:
55
- # ec2.call("DescribeInstances")
56
- # ec2.call("TerminateInstances", "InstanceId" => ["i-1234", "i-993j"]
57
- #
58
- def call(action, query={}, &blk)
59
- call!(action, expand(query)) do |code, data|
60
- case code
61
- when 200
62
- response = compact(data)
63
- when 400...500
64
- messages = Array(data["Response"]["Errors"]).map {|_, e| e["Message"] }
65
- raise InvalidRequest, messages.join(",")
66
- else
67
- msg = "unexpected response #{code} -> #{data.inspect}"
68
- raise InvalidRequest, msg
69
- end
70
-
71
- if blk
72
- blk.call(response)
73
- else
74
- response
75
- end
76
- end
9
+ def self.new(options)
10
+ $stderr.puts "WARNING: Swirl::EC2 will be deprecated. Use Swirl::AWS.new(:ec2) instead"
11
+ return AWS.new(:ec2, options)
77
12
  end
78
-
79
- def call!(action, query={}, &blk)
80
- # Hard coding this here until otherwise needed
81
- method = "POST"
82
-
83
- query["Action"] = action
84
- query["AWSAccessKeyId"] = @aws_access_key_id
85
- query["SignatureMethod"] = "HmacSHA256"
86
- query["SignatureVersion"] = "2"
87
- query["Timestamp"] = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
88
- query["Version"] = @version
89
-
90
- body = compile_sorted_form_data(query)
91
- body += "&" + ["Signature", compile_signature(method, body)].join("=")
92
-
93
- post(body) do |code, xml|
94
- if ENV["SWIRL_LOG"]
95
- puts response.body
96
- end
97
-
98
- data = Crack::XML.parse(xml)
99
- blk.call(code, data)
100
- end
101
- end
102
-
103
- def post(body, &blk)
104
- headers = { "Content-Type" => "application/x-www-form-urlencoded" }
105
-
106
- http = Net::HTTP.new(@url.host, @url.port)
107
- http.use_ssl = true
108
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
109
-
110
- request = Net::HTTP::Post.new(@url.request_uri, headers)
111
- request.body = body
112
-
113
- response = http.request(request)
114
- blk.call(response.code.to_i, response.body)
115
- end
116
-
117
- def inspect
118
- "<#{self.class.name} version: #{@version} url: #{@url} aws_access_key_id: #{@aws_access_key_id}>"
119
- end
120
-
121
13
  end
122
14
 
123
15
  end
data/lib/swirl/helpers.rb CHANGED
@@ -37,8 +37,8 @@ module Swirl
37
37
 
38
38
  def compact!(data)
39
39
  data.inject({}) do |com, (key, value)|
40
- if Lists.include?(key)
41
- converted = if value && value.has_key?("item")
40
+ if value.is_a?(Hash)
41
+ converted = if value.has_key?("item")
42
42
  items = value["item"]
43
43
  items ||= []
44
44
  items = items.is_a?(Array) ? items : [items]
@@ -39,13 +39,6 @@ class CompactorTest < Test::Unit::TestCase
39
39
  assert_equal expected, Compactor.compact(response)
40
40
  end
41
41
 
42
- test "makes value empty Array if nil" do
43
- response = { "Foo" => { "groupSet" => nil } }
44
- expected = { "groupSet" => [] }
45
-
46
- assert_equal expected, Compactor.compact(response)
47
- end
48
-
49
42
  test "traverses list values and compacts" do
50
43
  response = {
51
44
  "Foo" => {
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 6
9
- - 2
10
- version: 1.6.2
8
+ - 7
9
+ - 0
10
+ version: 1.7.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Blake Mizerany
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-22 00:00:00 -08:00
18
+ date: 2011-02-28 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -78,7 +78,7 @@ extra_rdoc_files:
78
78
  files:
79
79
  - LICENSE
80
80
  - README.md
81
- - list-types
81
+ - lib/swirl/aws.rb
82
82
  - lib/swirl/ec2.rb
83
83
  - lib/swirl/helpers.rb
84
84
  - lib/swirl.rb
data/list-types DELETED
@@ -1,36 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- begin
4
- require 'nokogiri'
5
- rescue LoadError
6
- abort <<-MSG
7
- Unable to load nokogiri.
8
- Ensure you have it installed and/or
9
- export RUBYOPT=rubygems
10
- MSG
11
- end
12
-
13
- require 'open-uri'
14
- require 'stringio'
15
- require 'pp'
16
-
17
- DefaultWSDL = "http://s3.amazonaws.com/ec2-downloads/2008-02-01.ec2.wsdl"
18
-
19
- wsdl_url = ARGV.shift || DefaultWSDL
20
- Wsdl = Nokogiri::XML.parse(open(wsdl_url))
21
-
22
- ##__END__
23
-
24
- list_keys = []
25
- item_types = Wsdl.search(%Q|//xs:complexType//xs:element[@name="item"]|)
26
- item_types.each do |item_type|
27
- ns, name = item_type["type"].split(":")
28
- next if ns != "tns"
29
- complex = item_type.parent.parent
30
- uses = Wsdl.search(%Q|//xs:element[@type="#{ns}:#{complex["name"]}"]|)
31
- uses.each do |u|
32
- list_keys << u["name"]
33
- end
34
- end
35
-
36
- pp list_keys.uniq