fog 0.0.93 → 0.0.94

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.
Files changed (58) hide show
  1. data/Gemfile +2 -1
  2. data/Gemfile.lock +13 -7
  3. data/bin/fog +6 -0
  4. data/fog.gemspec +40 -3
  5. data/lib/fog.rb +2 -1
  6. data/lib/fog/aws.rb +12 -8
  7. data/lib/fog/aws/parsers/s3/get_bucket_logging.rb +40 -0
  8. data/lib/fog/aws/parsers/s3/get_bucket_object_versions.rb +88 -0
  9. data/lib/fog/aws/parsers/s3/get_bucket_versioning.rb +24 -0
  10. data/lib/fog/aws/requests/ec2/associate_address.rb +3 -0
  11. data/lib/fog/aws/requests/ec2/describe_instances.rb +4 -3
  12. data/lib/fog/aws/requests/ec2/disassociate_address.rb +4 -0
  13. data/lib/fog/aws/requests/s3/get_bucket.rb +6 -5
  14. data/lib/fog/aws/requests/s3/get_bucket_logging.rb +53 -0
  15. data/lib/fog/aws/requests/s3/get_bucket_object_versions.rb +83 -0
  16. data/lib/fog/aws/requests/s3/get_bucket_versioning.rb +43 -0
  17. data/lib/fog/aws/requests/s3/get_object.rb +6 -1
  18. data/lib/fog/aws/requests/s3/get_object_acl.rb +8 -2
  19. data/lib/fog/aws/requests/s3/head_object.rb +4 -1
  20. data/lib/fog/aws/requests/s3/put_bucket_acl.rb +1 -1
  21. data/lib/fog/aws/requests/s3/put_bucket_logging.rb +87 -0
  22. data/lib/fog/aws/requests/s3/put_bucket_versioning.rb +40 -0
  23. data/lib/fog/aws/s3.rb +9 -1
  24. data/lib/fog/bin.rb +1 -1
  25. data/lib/fog/credentials.rb +6 -2
  26. data/lib/fog/vcloud.rb +288 -0
  27. data/lib/fog/vcloud/bin.rb +57 -0
  28. data/lib/fog/vcloud/parser.rb +34 -0
  29. data/lib/fog/vcloud/parsers/get_organization.rb +37 -0
  30. data/lib/fog/vcloud/parsers/get_vdc.rb +37 -0
  31. data/lib/fog/vcloud/parsers/get_versions.rb +46 -0
  32. data/lib/fog/vcloud/parsers/login.rb +40 -0
  33. data/lib/fog/vcloud/requests/get_organization.rb +55 -0
  34. data/lib/fog/vcloud/requests/get_vdc.rb +59 -0
  35. data/lib/fog/vcloud/requests/get_versions.rb +43 -0
  36. data/lib/fog/vcloud/requests/login.rb +46 -0
  37. data/lib/fog/vcloud/terremark/all.rb +9 -0
  38. data/lib/fog/vcloud/terremark/ecloud.rb +47 -0
  39. data/lib/fog/vcloud/terremark/ecloud/parsers/get_vdc.rb +59 -0
  40. data/lib/fog/vcloud/terremark/ecloud/requests/get_vdc.rb +94 -0
  41. data/lib/fog/vcloud/terremark/ecloud/requests/login.rb +27 -0
  42. data/lib/fog/vcloud/terremark/vcloud.rb +43 -0
  43. data/lib/fog/vcloud/terremark/vcloud/parsers/get_vdc.rb +34 -0
  44. data/lib/fog/vcloud/terremark/vcloud/requests/get_vdc.rb +65 -0
  45. data/spec/aws/requests/ec2/describe_instances_spec.rb +4 -4
  46. data/spec/spec_helper.rb +3 -1
  47. data/spec/vcloud/bin_spec.rb +31 -0
  48. data/spec/vcloud/requests/get_organization_spec.rb +46 -0
  49. data/spec/vcloud/requests/get_vdc_spec.rb +50 -0
  50. data/spec/vcloud/requests/get_versions_spec.rb +28 -0
  51. data/spec/vcloud/requests/login_spec.rb +8 -0
  52. data/spec/vcloud/spec_helper.rb +184 -0
  53. data/spec/vcloud/terremark/ecloud/requests/get_vdc_spec.rb +135 -0
  54. data/spec/vcloud/terremark/ecloud/requests/login_spec.rb +7 -0
  55. data/spec/vcloud/terremark/vcloud/requests/get_vdc_spec.rb +74 -0
  56. data/spec/vcloud/vcloud_spec.rb +17 -0
  57. data/tests/aws/requests/ec2/address_tests.rb +3 -0
  58. metadata +42 -5
@@ -5,7 +5,7 @@ module Fog
5
5
 
6
6
  def services
7
7
  services = []
8
- [::AWS, ::Local, ::Rackspace, ::Slicehost, ::Terremark].each do |service|
8
+ [::AWS, ::Local, ::Rackspace, ::Slicehost, ::Terremark, ::Vcloud].each do |service|
9
9
  if service.initialized?
10
10
  services << service
11
11
  end
@@ -10,9 +10,13 @@ module Fog
10
10
  @credential || :default
11
11
  end
12
12
 
13
+ def config_path
14
+ ENV["FOG_RC"] || '~/.fog'
15
+ end
16
+
13
17
  def credentials
14
18
  @credentials ||= begin
15
- path = File.expand_path('~/.fog')
19
+ path = File.expand_path(config_path)
16
20
  credentials = if File.exists?(path)
17
21
  File.open(path) do |file|
18
22
  YAML.load(file.read)
@@ -21,7 +25,7 @@ module Fog
21
25
  nil
22
26
  end
23
27
  unless credentials && credentials[credential]
24
- print("\n To run as '#{credential}', add the following to ~/.fog\n")
28
+ print("\n To run as '#{credential}', add the following to #{config_path}\n")
25
29
  yml = <<-YML
26
30
 
27
31
  :#{credential}:
@@ -0,0 +1,288 @@
1
+ module URI
2
+ class Generic
3
+ def host_url
4
+ @host_url ||= "#{self.scheme}://#{self.host}#{self.port ? ":#{self.port}" : ''}"
5
+ end
6
+ end
7
+ end
8
+
9
+ module Fog
10
+ module Vcloud
11
+
12
+ class UnsupportedVersion < Exception ; end
13
+
14
+ module Options
15
+ REQUIRED = [:versions_uri, :username, :password]
16
+ OPTIONAL = [:module, :version]
17
+ ALL = REQUIRED + OPTIONAL
18
+ end
19
+
20
+ class Real
21
+
22
+ attr_accessor :login_uri
23
+ attr_reader :supported_versions
24
+
25
+ def initialize(options = {})
26
+ @connections = {}
27
+ @versions_uri = URI.parse(options[:versions_uri])
28
+ @module = options[:module]
29
+ @version = options[:version]
30
+ @username = options[:username]
31
+ @password = options[:password]
32
+ @login_uri = get_login_uri
33
+ end
34
+
35
+ def default_organization_uri
36
+ @default_organization_uri ||= begin
37
+ unless @login_results
38
+ do_login
39
+ end
40
+ org_list = @login_results.body.organizations
41
+ if organization = @login_results.body.organizations.first
42
+ URI.parse(organization[:href])
43
+ else
44
+ nil
45
+ end
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def supported_version_ids
52
+ @supported_versions.map { |version| version.version }
53
+ end
54
+
55
+ def get_login_uri
56
+ check_versions
57
+ URI.parse(@supported_versions.detect {|version| version.version == @version }.login_url)
58
+ end
59
+
60
+ # Load up @all_versions and @supported_versions from the provided :versions_uri
61
+ # If there are no supported versions raise an error
62
+ # And choose a default version is none is specified
63
+ def check_versions
64
+ @all_versions = get_versions.body
65
+ @supported_versions = @all_versions.select { |version| version.supported == true }
66
+
67
+ if @supported_versions.empty?
68
+ raise UnsupportedVersion.new("No supported versions found @ #{@version_uri}")
69
+ end
70
+
71
+ unless @version
72
+ @version = supported_version_ids.sort.first
73
+ end
74
+ end
75
+
76
+ # Don't need to set the cookie for these or retry them if the cookie timed out
77
+ def unauthenticated_request(params)
78
+ do_request(params)
79
+ end
80
+
81
+ # Use this to set the Authorization header for login
82
+ def authorization_header
83
+ "Basic #{Base64.encode64("#{@username}:#{@password}").chomp!}"
84
+ end
85
+
86
+ # login handles the auth, but we just need the Set-Cookie
87
+ # header from that call.
88
+ def do_login
89
+ @login_results = login
90
+ @cookie = @login_results.headers['Set-Cookie']
91
+ end
92
+
93
+ # If the cookie isn't set, do a get_organizations call to set it
94
+ # and try the request.
95
+ # If we get an Unauthoried error, we assume the token expired, re-auth and try again
96
+ def request(params)
97
+ unless @cookie
98
+ do_login
99
+ end
100
+ begin
101
+ do_request(params)
102
+ rescue Excon::Errors::Unauthorized => e
103
+ do_login
104
+ do_request(params)
105
+ end
106
+ end
107
+
108
+ # Actually do the request
109
+ def do_request(params)
110
+ if params[:uri].is_a?(String)
111
+ params[:uri] = URI.parse(params[:uri])
112
+ end
113
+ @connections[params[:uri].host_url] ||= Fog::Connection.new(params[:uri].host_url)
114
+ headers = params[:headers] || {}
115
+ if @cookie
116
+ headers.merge!('Cookie' => @cookie)
117
+ end
118
+ @connections[params[:uri].host_url].request({
119
+ :body => params[:body],
120
+ :expects => params[:expects],
121
+ :headers => headers,
122
+ :method => params[:method],
123
+ :parser => params[:parser],
124
+ :path => params[:uri].path
125
+ })
126
+ end
127
+ end
128
+
129
+ class Mock < Real
130
+ DATA =
131
+ {
132
+ :versions => [
133
+ { :version => "v0.8", :login_url => "https://fakey.com/api/v0.8/login", :supported => true }
134
+ ],
135
+ :organizations =>
136
+ [
137
+ {
138
+ :info => {
139
+ :href => "https://fakey.com/api/v0.8/org/1",
140
+ :name => "Boom Inc.",
141
+ },
142
+ :vdcs => [
143
+ { :href => "https://fakey.com/api/v0.8/vdc/21",
144
+ :name => "Boomstick",
145
+ :storage => { :used => 105, :allocated => 200 },
146
+ :cpu => { :allocated => 10000 },
147
+ :memory => { :allocated => 20480 },
148
+ :networks => [
149
+ { :href => "https://fakey.com/api/v0.8/network/31",
150
+ :name => "1.2.3.0/24",
151
+ :subnet => "1.2.3.0/24",
152
+ :gateway => "1.2.3.1",
153
+ :netmask => "255.255.255.0",
154
+ :fencemode => "isolated"
155
+ },
156
+ { :href => "https://fakey.com/api/v0.8/network/32",
157
+ :name => "4.5.6.0/24",
158
+ :subnet => "4.5.6.0/24",
159
+ :gateway => "4.5.6.1",
160
+ :netmask => "255.255.255.0",
161
+ :fencemode => "isolated"
162
+ },
163
+ ],
164
+ :vms => [
165
+ { :href => "https://fakey.com/api/v0.8/vap/41",
166
+ :name => "Broom 1"
167
+ },
168
+ { :href => "https://fakey.com/api/v0.8/vap/42",
169
+ :name => "Broom 2"
170
+ },
171
+ { :href => "https://fakey.com/api/v0.8/vap/43",
172
+ :name => "Email!"
173
+ }
174
+ ],
175
+ :public_ips => [
176
+ { :id => 51,
177
+ :name => "99.1.2.3"
178
+ },
179
+ { :id => 52,
180
+ :name => "99.1.2.4"
181
+ },
182
+ { :id => 53,
183
+ :name => "99.1.9.7"
184
+ }
185
+ ]
186
+ },
187
+ { :href => "https://fakey.com/api/v0.8/vdc/22",
188
+ :storage => { :used => 40, :allocated => 150 },
189
+ :cpu => { :allocated => 1000 },
190
+ :memory => { :allocated => 2048 },
191
+ :name => "Rock-n-Roll",
192
+ :networks => [
193
+ { :href => "https://fakey.com/api/v0.8/network/33",
194
+ :name => "7.8.9.0/24",
195
+ :subnet => "7.8.9.0/24",
196
+ :gateway => "7.8.9.1",
197
+ :netmask => "255.255.255.0",
198
+ :fencemode => "isolated"
199
+ }
200
+ ],
201
+ :vms => [
202
+ { :href => "https://fakey.com/api/v0.8/vap/44",
203
+ :name => "Master Blaster"
204
+ }
205
+ ],
206
+ :public_ips => [
207
+ { :id => 54,
208
+ :name => "99.99.99.99"
209
+ }
210
+ ]
211
+ }
212
+ ]
213
+ }
214
+ ]
215
+ }
216
+
217
+ def initialize(credentials = {})
218
+ require 'builder'
219
+ @versions_uri = URI.parse('https://vcloud.fakey.com/api/versions')
220
+ @login_uri = get_login_uri
221
+ end
222
+
223
+ def xmlns
224
+ { "xmlns" => "http://www.vmware.com/vcloud/v0.8",
225
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
226
+ "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema" }
227
+ end
228
+
229
+ def mock_it(parser, status, mock_data, mock_headers = {})
230
+ body = Nokogiri::XML::SAX::PushParser.new(parser)
231
+ body << mock_data
232
+ body.finish
233
+ response = Excon::Response.new
234
+ response.status = status
235
+ response.body = parser.response
236
+ response.headers = mock_headers
237
+ response
238
+ end
239
+
240
+ def mock_error(expected, status, body='', headers={})
241
+ raise Excon::Errors::Unauthorized.new("Expected(#{expected}) <=> Actual(#{status})")
242
+ end
243
+
244
+ def mock_data
245
+ DATA
246
+ end
247
+
248
+ end
249
+
250
+ class <<self
251
+ def new(credentials = {})
252
+ unless @required
253
+ require 'fog/vcloud/parser'
254
+ require 'fog/vcloud/terremark/vcloud'
255
+ require 'fog/vcloud/terremark/ecloud'
256
+ require 'fog/vcloud/requests/get_organization'
257
+ require 'fog/vcloud/requests/get_vdc'
258
+ require 'fog/vcloud/requests/get_versions'
259
+ require 'fog/vcloud/requests/login'
260
+ require 'fog/vcloud/parsers/get_organization'
261
+ require 'fog/vcloud/parsers/get_vdc'
262
+ require 'fog/vcloud/parsers/get_versions'
263
+ require 'fog/vcloud/parsers/login'
264
+
265
+ Struct.new("VcloudLink", :rel, :href, :type, :name)
266
+ Struct.new("VcloudVdc", :links, :href, :type, :name, :xmlns, :allocation_model, :description)
267
+ Struct.new("VcloudOrganization", :links, :name, :href, :type, :xmlns, :description)
268
+ Struct.new("VcloudVersion", :version, :login_url, :supported)
269
+ Struct.new("VcloudOrgList", :organizations, :xmlns)
270
+ Struct.new("VcloudOrgLink", :name, :href, :type)
271
+ @required = true
272
+ end
273
+
274
+ instance = if Fog.mocking?
275
+ Fog::Vcloud::Mock.new(credentials)
276
+ else
277
+ Fog::Vcloud::Real.new(credentials)
278
+ end
279
+
280
+ if mod = credentials[:module]
281
+ instance.extend eval "#{mod}"
282
+ end
283
+
284
+ instance
285
+ end
286
+ end
287
+ end
288
+ end
@@ -0,0 +1,57 @@
1
+ module Vcloud
2
+ class << self
3
+
4
+ def services
5
+ if Fog.credentials.has_key?(:vcloud)
6
+ Fog.credentials[:vcloud].keys.sort { |a,b| a.to_s <=> b.to_s }
7
+ else
8
+ []
9
+ end
10
+ end
11
+
12
+ def registered_services
13
+ Vcloud.services.map { |service| ":" << service.to_s }.join(", ")
14
+ end
15
+
16
+ def complete_service_options?(service)
17
+ if Fog.credentials.has_key?(:vcloud)
18
+ if Fog.credentials[:vcloud].has_key?(service)
19
+ service = Fog.credentials[:vcloud][service]
20
+ if Fog::Vcloud::Options::REQUIRED.all? { |option| service.has_key?(option) }
21
+ return true
22
+ end
23
+ end
24
+ end
25
+ false
26
+ end
27
+
28
+ if Vcloud.services.all? { |service| Vcloud.complete_service_options?(service) }
29
+
30
+ def initialized?
31
+ true
32
+ end
33
+
34
+ def startup_notice
35
+ puts "You have acess to the following Vcloud services: #{Vcloud.registered_services}."
36
+ end
37
+
38
+ def [](service)
39
+ @@connections ||= Hash.new do |hash, key|
40
+ if credentials = Fog.credentials[:vcloud][key]
41
+ hash[key] = Fog::Vcloud.new(credentials.reject { |k,value| Fog::Vcloud::Options::ALL.include?(value) })
42
+ else
43
+ raise ArgumentError.new("Unregistered service: :#{key}. Registered services are: #{Vcloud.registered_services}")
44
+ end
45
+ end
46
+ @@connections[service]
47
+ end
48
+
49
+ else
50
+
51
+ def initialized?
52
+ false
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,34 @@
1
+ module Fog
2
+ module Parsers
3
+ module Vcloud
4
+ class Base < Fog::Parsers::Base
5
+
6
+ private
7
+
8
+ def generate_link(attributes)
9
+ link = Struct::VcloudLink.new
10
+ until attributes.empty?
11
+ link[attributes.shift.downcase] = attributes.shift
12
+ end
13
+ link
14
+ end
15
+
16
+ def handle_root(attributes)
17
+ root = {}
18
+ until attributes.empty?
19
+ if attributes.first.is_a?(Array)
20
+ attribute = attributes.shift
21
+ root[attribute.first.downcase] = attribute.last
22
+ else
23
+ root[attributes.shift.downcase] = attributes.shift
24
+ end
25
+ end
26
+ @response.href = root['href']
27
+ @response.name = root['name']
28
+ @response.type = root['type']
29
+ @response.xmlns = root['xmlns']
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,37 @@
1
+ module Fog
2
+ module Parsers
3
+ module Vcloud
4
+
5
+ class GetOrganization < Fog::Parsers::Vcloud::Base
6
+ #
7
+ # Based off of:
8
+ # http://support.theenterprisecloud.com/kb/default.asp?id=540&Lang=1&SID=
9
+ #
10
+ # vCloud API Guide v0.9 - Page 26
11
+ #
12
+
13
+ def reset
14
+ @response = Struct::VcloudOrganization.new([])
15
+ end
16
+
17
+ def start_element(name, attributes)
18
+ @value = ''
19
+ case name
20
+ when 'Link'
21
+ @response.links << generate_link(attributes)
22
+ when 'Org'
23
+ handle_root(attributes)
24
+ end
25
+ end
26
+
27
+ def end_element(name)
28
+ if name == 'Description'
29
+ @response.description = @value
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+ end
37
+ end