steamcannon-deltacloud-core 0.1.1.3 → 0.1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/bin/deltacloudd +7 -1
  2. data/config.ru +19 -1
  3. data/deltacloud.rb +20 -1
  4. data/lib/deltacloud/backend_capability.rb +33 -1
  5. data/lib/deltacloud/base_driver.rb +1 -1
  6. data/lib/deltacloud/base_driver/base_driver.rb +62 -73
  7. data/lib/deltacloud/base_driver/features.rb +6 -6
  8. data/lib/deltacloud/drivers/azure/azure_driver.rb +32 -1
  9. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +107 -23
  10. data/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb +18 -0
  11. data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +0 -1
  12. data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +20 -5
  13. data/lib/deltacloud/drivers/mock/mock_driver.rb +1 -1
  14. data/lib/deltacloud/drivers/rackspace/rackspace_client.rb +1 -1
  15. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +28 -1
  16. data/lib/deltacloud/hardware_profile.rb +17 -0
  17. data/lib/deltacloud/helpers.rb +18 -0
  18. data/lib/deltacloud/helpers/application_helper.rb +2 -2
  19. data/lib/deltacloud/helpers/blob_stream.rb +5 -1
  20. data/lib/deltacloud/helpers/conversion_helper.rb +1 -2
  21. data/lib/deltacloud/helpers/hardware_profiles_helper.rb +17 -0
  22. data/lib/deltacloud/method_serializer.rb +1 -1
  23. data/lib/deltacloud/models/base_model.rb +1 -1
  24. data/lib/deltacloud/models/blob.rb +3 -1
  25. data/lib/deltacloud/models/bucket.rb +2 -1
  26. data/lib/deltacloud/models/image.rb +1 -1
  27. data/lib/deltacloud/models/instance.rb +1 -2
  28. data/lib/deltacloud/models/instance_profile.rb +2 -1
  29. data/lib/deltacloud/models/key.rb +1 -1
  30. data/lib/deltacloud/models/load_balancer.rb +1 -1
  31. data/lib/deltacloud/models/realm.rb +1 -1
  32. data/lib/deltacloud/models/storage_snapshot.rb +1 -1
  33. data/lib/deltacloud/models/storage_volume.rb +1 -1
  34. data/lib/deltacloud/state_machine.rb +17 -0
  35. data/lib/deltacloud/validation.rb +18 -0
  36. data/lib/drivers.rb +69 -43
  37. data/lib/sinatra/lazy_auth.rb +1 -1
  38. data/lib/sinatra/rabbit.rb +5 -5
  39. data/lib/sinatra/rack_driver_select.rb +29 -0
  40. data/server.rb +45 -16
  41. data/views/api/drivers.xml.haml +6 -0
  42. data/views/api/show.html.haml +2 -2
  43. data/views/api/show.xml.haml +1 -1
  44. data/views/buckets/index.html.haml +2 -1
  45. data/views/buckets/show.html.haml +4 -3
  46. data/views/errors/backend_error.xml.haml +1 -1
  47. data/views/images/index.xml.haml +5 -1
  48. data/views/layout.html.haml +1 -1
  49. metadata +6 -5
  50. data/lib/deltacloud/drivers/gogrid/test.rb +0 -13
data/bin/deltacloudd CHANGED
@@ -36,6 +36,9 @@ BANNER
36
36
  opts.on( '-p', '--port PORT', 'Use PORT (default: 3001)') do |port|
37
37
  ENV["API_PORT"] = port
38
38
  end
39
+ opts.on( '-P', '--provider PROVIDER', 'Use PROVIDER (default is set in the driver)') do |provider|
40
+ ENV['API_PROVIDER'] = provider
41
+ end
39
42
  opts.on( '-e', '--env ENV', 'Environment (default: "development")') { |env| options[:env] = env }
40
43
  opts.on( '-h', '--help', '') { options[:help] = true }
41
44
  end
@@ -55,7 +58,10 @@ end
55
58
  ENV["API_HOST"] = "localhost" unless ENV["API_HOST"]
56
59
  ENV["API_PORT"] = "3001" unless ENV["API_PORT"]
57
60
 
58
- puts "Starting Deltacloud API :: #{ENV["API_DRIVER"]} :: http://#{ENV["API_HOST"]}:#{ENV["API_PORT"]}/api"
61
+ msg = "Starting Deltacloud API :: #{ENV["API_DRIVER"]} "
62
+ msg << ":: #{ENV['API_PROVIDER']} " if ENV['API_PROVIDER']
63
+ msg << ":: http://#{ENV["API_HOST"]}:#{ENV["API_PORT"]}/api"
64
+ puts msg
59
65
  puts
60
66
 
61
67
  dirname="#{File.dirname(__FILE__)}/.."
data/config.ru CHANGED
@@ -1,7 +1,25 @@
1
+ #
2
+ # Copyright (C) 2009,2010 Red Hat, Inc.
3
+ #
4
+ # Licensed to the Apache Software Foundation (ASF) under one or more
5
+ # contributor license agreements. See the NOTICE file distributed with
6
+ # this work for additional information regarding copyright ownership. The
7
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance with the
9
+ # License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
+ # License for the specific language governing permissions and limitations
17
+ # under the License.
18
+
1
19
  require 'rubygems'
2
- require 'sinatra'
3
20
 
4
21
  $:.unshift File.join(File.dirname(__FILE__), '.')
5
22
 
6
23
  require 'server.rb'
24
+
7
25
  run Sinatra::Application
data/deltacloud.rb CHANGED
@@ -1,6 +1,25 @@
1
- # Add ./lib into load path
1
+ #
2
+ # Copyright (C) 2009,2010 Red Hat, Inc.
3
+ #
4
+ # Licensed to the Apache Software Foundation (ASF) under one or more
5
+ # contributor license agreements. See the NOTICE file distributed with
6
+ # this work for additional information regarding copyright ownership. The
7
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance with the
9
+ # License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
+ # License for the specific language governing permissions and limitations
17
+ # under the License.
18
+
2
19
  $:.unshift File.join(File.dirname(__FILE__), 'lib')
3
20
 
21
+ require 'drivers'
22
+
4
23
  require 'deltacloud/base_driver'
5
24
  require 'deltacloud/hardware_profile'
6
25
  require 'deltacloud/state_machine'
@@ -1,7 +1,26 @@
1
+ #
2
+ # Copyright (C) 2009, 2010 Red Hat, Inc.
3
+ #
4
+ # Licensed to the Apache Software Foundation (ASF) under one or more
5
+ # contributor license agreements. See the NOTICE file distributed with
6
+ # this work for additional information regarding copyright ownership. The
7
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance with the
9
+ # License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
+ # License for the specific language governing permissions and limitations
17
+ # under the License.
18
+
1
19
  module Deltacloud::BackendCapability
2
20
 
3
21
  class Failure < StandardError
4
22
  attr_reader :capability
23
+
5
24
  def initialize(capability, msg='')
6
25
  super(msg)
7
26
  @capability = capability
@@ -9,13 +28,26 @@ module Deltacloud::BackendCapability
9
28
  end
10
29
 
11
30
  attr_reader :capability
31
+
12
32
  def with_capability(capability)
13
33
  @capability = capability
14
34
  end
15
35
 
36
+ def has_capability?(backend)
37
+ !capability or backend.has_capability?(capability)
38
+ end
39
+
16
40
  def check_capability(backend)
17
- if capability and !backend.respond_to?(capability)
41
+ if !has_capability?(backend)
18
42
  raise Failure.new(capability, "#{capability} capability not supported by backend #{backend.class.name}")
19
43
  end
20
44
  end
45
+
46
+ module Helpers
47
+ def operations_for_collection(collection)
48
+ collections[collection].operations.values.select { |op| op.has_capability?(driver) }
49
+ end
50
+ end
51
+
52
+ helpers Helpers
21
53
  end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2009 Red Hat, Inc.
2
+ # Copyright (C) 2009,2010 Red Hat, Inc.
3
3
  #
4
4
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
5
  # contributor license agreements. See the NOTICE file distributed with
@@ -42,7 +42,7 @@ module Deltacloud
42
42
  end
43
43
 
44
44
  class BaseDriver
45
-
45
+
46
46
  def self.define_hardware_profile(name,&block)
47
47
  @hardware_profiles ||= []
48
48
  hw_profile = @hardware_profiles.find{|e| e.name == name}
@@ -126,100 +126,90 @@ module Deltacloud
126
126
  actions
127
127
  end
128
128
 
129
+ ## Capabilities
130
+ # The rabbit dsl supports declaring a capability that is required
131
+ # in the backend driver for the call to succeed. A driver can
132
+ # provide a capability by implementing the method with the same
133
+ # name as the capability. Below is a list of the capabilities as
134
+ # the expected method signatures.
135
+ #
136
+ # Following the capability list are the resource member show
137
+ # methods. They each require that the corresponding collection
138
+ # method be defined
139
+ #
140
+ # TODO: standardize all of these to the same signature (credentials, opts)
141
+ #
142
+ # def realms(credentials, opts=nil)
143
+ #
144
+ # def images(credentials, ops)
145
+ #
146
+ # def instances(credentials, ops)
147
+ # def create_instance(credentials, image_id, opts)
148
+ # def start_instance(credentials, id)
149
+ # def stop_instance(credentials, id)
150
+ # def reboot_instance(credentials, id)
151
+ #
152
+ # def storage_volumes(credentials, ops)
153
+ #
154
+ # def storage_snapshots(credentials, ops)
155
+ #
156
+ # def buckets(credentials, opts = nil)
157
+ # def create_bucket(credentials, name, opts=nil)
158
+ # def delete_bucket(credentials, name, opts=nil)
159
+ #
160
+ # def blobs(credentials, opts = nil)
161
+ # def blob_data(credentials, bucket_id, blob_id, opts)
162
+ # def create_blob(credentials, bucket_id, blob_id, blob_data, opts=nil)
163
+ # def delete_blob(credentials, bucket_id, blob_id, opts=nil)
164
+ #
165
+ # def keys(credentials, opts)
166
+ # def create_key(credentials, opts)
167
+ # def destroy_key(credentials, opts)
168
+
129
169
  def realm(credentials, opts)
130
- realms = realms(credentials, opts)
131
- return realms.first unless realms.empty?
132
- nil
133
- end
134
-
135
- def realms(credentials, opts=nil)
136
- []
170
+ realms = realms(credentials, opts).first if has_capability?(:realms)
137
171
  end
138
172
 
139
173
  def image(credentials, opts)
140
- images = images(credentials, opts)
141
- return images.first unless images.empty?
142
- nil
143
- end
144
-
145
- def images(credentials, ops)
146
- []
174
+ images(credentials, opts).first if has_capability?(:images)
147
175
  end
148
176
 
149
177
  def instance(credentials, opts)
150
- instances = instances(credentials, opts)
151
- return instances.first unless instances.empty?
152
- nil
153
- end
154
-
155
- def instances(credentials, ops)
156
- []
157
- end
158
-
159
- def create_instance(credentials, image_id, opts)
160
- end
161
- def start_instance(credentials, id)
162
- end
163
- def stop_instance(credentials, id)
164
- end
165
- def reboot_instance(credentials, id)
178
+ instances(credentials, opts).first if has_capability?(:instances)
166
179
  end
167
180
 
168
181
  def storage_volume(credentials, opts)
169
- volumes = storage_volumes(credentials, opts)
170
- return volumes.first unless volumes.empty?
171
- nil
172
- end
173
-
174
- def storage_volumes(credentials, ops)
175
- []
182
+ storage_volumes(credentials, opts).first if has_capability?(:storage_volumes)
176
183
  end
177
184
 
178
185
  def storage_snapshot(credentials, opts)
179
- snapshots = storage_snapshots(credentials, opts)
180
- return snapshots.first unless snapshots.empty?
181
- nil
182
- end
183
-
184
- def storage_snapshots(credentials, ops)
185
- []
186
- end
187
-
188
- def buckets(credentials, opts = nil)
189
- #list of buckets belonging to account
190
- []
186
+ storage_snapshots(credentials, opts).first if has_capability?(:storage_snapshots)
191
187
  end
192
188
 
193
189
  def bucket(credentials, opts = nil)
194
- #list of objects within bucket
195
- list = buckets(credentials, opts)
196
- return list.first unless list.empty?
197
- nil
198
- end
199
-
200
- def create_bucket(credentials, name, opts=nil)
201
- end
202
-
203
- def delete_bucket(credentials, name, opts=nil)
190
+ #list of objects within bucket
191
+ buckets(credentials, opts).first if has_capability?(:buckets)
204
192
  end
205
-
206
- def blobs(credentials, opts = nil)
207
- []
208
- end
209
-
193
+
210
194
  def blob(credentials, opts = nil)
211
- list = blobs(credentials, opts)
212
- return list.first unless list.empty?
195
+ blobs(credentials, opts).first if has_capability?(:blobs)
213
196
  end
214
197
 
215
- def blob_data(credentials, bucket_id, blob_id, opts)
198
+ def key(credentials, opts=nil)
199
+ keys(credentials, opts).first if has_capability?(:keys)
216
200
  end
217
201
 
218
- def create_blob(credentials, bucket_id, blob_id, blob_data, opts=nil)
219
- end
202
+ MEMBER_SHOW_METHODS =
203
+ [ :realm, :image, :instance, :storage_volume, :bucket, :blob, :key ]
220
204
 
221
- def delete_blob(credentials, bucket_id, blob_id, opts=nil)
205
+ def has_capability?(capability)
206
+ if MEMBER_SHOW_METHODS.include?(capability.to_sym)
207
+ has_capability?(capability.to_s.pluralize)
208
+ else
209
+ respond_to?(capability)
210
+ end
222
211
  end
212
+
223
213
 
224
214
  def filter_on(collection, attribute, opts)
225
215
  return collection if opts.nil?
@@ -237,8 +227,7 @@ module Deltacloud
237
227
  end
238
228
 
239
229
  def has_collection?(collection)
240
- return true if self.supported_collections.include?(collection)
241
- return false
230
+ supported_collections.include?(collection)
242
231
  end
243
232
 
244
233
  def catched_exceptions_list
@@ -117,6 +117,12 @@ module Deltacloud
117
117
  self.class.features[collection] || []
118
118
  end
119
119
 
120
+ def features_for_operation(collection, operation)
121
+ features(collection).select do |f|
122
+ f.operations.detect { |o| o.name == operation }
123
+ end
124
+ end
125
+
120
126
  #
121
127
  # Declaration of optional features
122
128
  #
@@ -185,11 +191,5 @@ module Deltacloud
185
191
  end
186
192
  end
187
193
 
188
- declare_feature :instances, :public_ip do
189
- operation :create do
190
- param :public_ip, :string, :optional
191
- end
192
- end
193
-
194
194
  end
195
195
  end
@@ -17,8 +17,9 @@
17
17
  # under the License.
18
18
 
19
19
  #Windows Azure (WAZ) gem at http://github.com/johnnyhalife/waz-storage
20
- require 'waz-blobs'
21
20
  require 'deltacloud/base_driver'
21
+ require 'waz-blobs'
22
+
22
23
  module Deltacloud
23
24
  module Drivers
24
25
  module Azure
@@ -46,6 +47,9 @@ class AzureDriver < Deltacloud::BaseDriver
46
47
  # Create bucket
47
48
  #--
48
49
  def create_bucket(credentials, name, opts)
50
+ #for whatever reason, bucket names MUST be lowercase...
51
+ #http://msdn.microsoft.com/en-us/library/dd135715.aspx
52
+ name.downcase!
49
53
  bucket = nil
50
54
  azure_connect(credentials)
51
55
  safely do
@@ -87,6 +91,33 @@ class AzureDriver < Deltacloud::BaseDriver
87
91
  yield WAZ::Blobs::Container.find(bucket_id)[blob_id].value
88
92
  end
89
93
 
94
+ #--
95
+ # Create Blob
96
+ #--
97
+ def create_blob(credentials, bucket_id, blob_id, blob_data, opts=nil)
98
+ azure_connect(credentials)
99
+ #get a handle to the bucket in order to put there
100
+ the_bucket = WAZ::Blobs::Container.find(bucket_id)
101
+ the_bucket.store(blob_id, blob_data[:tempfile], blob_data[:type])
102
+ Blob.new( { :id => blob_id,
103
+ :bucket => bucket_id,
104
+ :content_lengh => blob_data[:tempfile].length,
105
+ :content_type => blob_data[:type],
106
+ :last_modified => ''
107
+ } )
108
+ end
109
+
110
+ #--
111
+ # Delete Blob
112
+ #--
113
+ def delete_blob(credentials, bucket_id, blob_id, opts=nil)
114
+ azure_connect(credentials)
115
+ #get a handle to bucket and blob, and destroy!
116
+ the_bucket = WAZ::Blobs::Container.find(bucket_id)
117
+ the_blob = the_bucket[blob_id]
118
+ the_blob.destroy!
119
+ end
120
+
90
121
  private
91
122
 
92
123
  def azure_connect(credentials)
@@ -1,5 +1,4 @@
1
- #
2
- # Copyright (C) 2010 Red Hat, Inc.
1
+ # Copyright (C) 2009, 2010 Red Hat, Inc.
3
2
  #
4
3
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
4
  # contributor license agreements. See the NOTICE file distributed with
@@ -41,11 +40,12 @@ module Deltacloud
41
40
 
42
41
  feature :instances, :user_data
43
42
  feature :instances, :authentication_key
44
- feature :instances, :public_ip
45
43
  feature :instances, :security_group
46
44
  feature :images, :owner_id
47
45
  feature :buckets, :bucket_location
48
46
 
47
+ DEFAULT_REGION = 'us-east-1'
48
+
49
49
  define_hardware_profile('t1.micro') do
50
50
  cpu 1
51
51
  memory 0.63 * 1024
@@ -121,14 +121,6 @@ module Deltacloud
121
121
  stopped.to( :finish ) .automatically
122
122
  end
123
123
 
124
- def valid_credentials?(credentials)
125
- # FIXME: We need to do this call to determine if
126
- # EC2 is working with given credentials. There is no
127
- # other way to check, if given credentials are valid or not.
128
- realms = realms(credentials) rescue false
129
- return realms ? true : false
130
- end
131
-
132
124
  def images(credentials, opts={})
133
125
  ec2 = new_client(credentials)
134
126
  img_arr = []
@@ -168,6 +160,16 @@ module Deltacloud
168
160
  inst_arr = ec2.describe_instances.collect do |instance|
169
161
  convert_instance(instance) if instance
170
162
  end.flatten
163
+ tags = ec2.describe_tags(
164
+ 'Filter.1.Name' => 'resource-type', 'Filter.1.Value' => 'instance'
165
+ )
166
+ inst_arr.each do |inst|
167
+ name_tag = tags.select { |t| (t[:aws_resource_id] == inst.id) and t[:aws_key] == 'name' }
168
+ unless name_tag.empty?
169
+ inst.name = name_tag.first[:aws_value]
170
+ end
171
+ end
172
+ delete_unused_tags(credentials, inst_arr.collect {|inst| inst.id})
171
173
  end
172
174
  inst_arr = filter_on( inst_arr, :id, opts )
173
175
  filter_on( inst_arr, :state, opts )
@@ -183,8 +185,8 @@ module Deltacloud
183
185
  instance_options.merge!(:group_ids => opts[:security_group]) if opts[:security_group]
184
186
  safely do
185
187
  new_instance = convert_instance(ec2.launch_instances(image_id, instance_options).first)
186
- if opts[:public_ip]
187
- ec2.associate_address(new_instance.id, opts[:public_ip])
188
+ if opts[:name]
189
+ tag_instance(credentials, new_instance, opts[:name])
188
190
  end
189
191
  new_instance
190
192
  end
@@ -202,7 +204,9 @@ module Deltacloud
202
204
  def destroy_instance(credentials, instance_id)
203
205
  ec2 = new_client(credentials)
204
206
  puts "Terminating instance #{instance_id}"
207
+ instance_id = instance_id
205
208
  if ec2.terminate_instances([instance_id])
209
+ untag_instance(credentials, instance_id)
206
210
  instance(credentials, instance_id)
207
211
  else
208
212
  raise Deltacloud::BackendError.new(500, "Instance", "Instance cannot be terminated", "")
@@ -221,10 +225,6 @@ module Deltacloud
221
225
  end
222
226
  end
223
227
 
224
- def key(credentials, opts={})
225
- keys(credentials, :id => opts[:id]).first
226
- end
227
-
228
228
  def create_key(credentials, opts={})
229
229
  ec2 = new_client(credentials)
230
230
  safely do
@@ -319,14 +319,18 @@ module Deltacloud
319
319
  #--
320
320
  def delete_blob(credentials, bucket_id, blob_id, opts=nil)
321
321
  s3_client = new_client(credentials, :s3)
322
- s3_client.interface.delete(bucket_id, blob_id)
322
+ safely do
323
+ s3_client.interface.delete(bucket_id, blob_id)
324
+ end
323
325
  end
324
326
 
325
327
 
326
328
  def blob_data(credentials, bucket_id, blob_id, opts)
327
329
  s3_client = new_client(credentials, :s3)
328
- s3_client.interface.get(bucket_id, blob_id) do |chunk|
329
- yield chunk
330
+ safely do
331
+ s3_client.interface.get(bucket_id, blob_id) do |chunk|
332
+ yield chunk
333
+ end
330
334
  end
331
335
  end
332
336
 
@@ -401,12 +405,82 @@ module Deltacloud
401
405
  end
402
406
  end
403
407
 
408
+ def valid_credentials?(credentials)
409
+ retval = true
410
+ begin
411
+ realms(credentials)
412
+ rescue Deltacloud::BackendError
413
+ retval = false
414
+ end
415
+ retval
416
+ end
417
+
404
418
  private
405
419
 
406
420
  def new_client(credentials, type = :ec2)
407
- case type
408
- when :ec2 then Aws::Ec2.new(credentials.user, credentials.password)
409
- when :s3 then Aws::S3.new(credentials.user, credentials.password)
421
+ klass = case type
422
+ when :elb then Aws::Elb
423
+ when :ec2 then Aws::Ec2
424
+ when :s3 then Aws::S3
425
+ end
426
+ klass.new(credentials.user, credentials.password, :server => endpoint_for_service(type))
427
+ end
428
+
429
+ DEFAULT_SERVICE_ENDPOINTS = {
430
+ 'ec2' => {
431
+ 'ap-southeast-1' => 'ec2.ap-southeast-1.amazonaws.com',
432
+ 'eu-west-1' => 'ec2.eu-west-1.amazonaws.com',
433
+ 'us-east-1' => 'ec2.us-east-1.amazonaws.com',
434
+ 'us-west-1' => 'ec2.us-west-1.amazonaws.com'
435
+ },
436
+
437
+ 'elb' => {
438
+ 'ap-southeast-1' => 'elasticloadbalancing.ap-southeast-1.amazonaws.com',
439
+ 'eu-west-1' => 'elasticloadbalancing.eu-west-1.amazonaws.com',
440
+ 'us-east-1' => 'elasticloadbalancing.us-east-1.amazonaws.com',
441
+ 'us-west-1' => 'elasticloadbalancing.us-west-1.amazonaws.com'
442
+ },
443
+
444
+ 's3' => {
445
+ 'ap-southeast-1' => 's3.amazonaws.com',
446
+ 'eu-west-1' => 's3.amazonaws.com',
447
+ 'us-east-1' => 's3.amazonaws.com',
448
+ 'us-west-1' => 's3.amazonaws.com'
449
+ }
450
+ }
451
+
452
+ def endpoint_for_service(service)
453
+ endpoint = (Thread.current[:provider] || ENV['API_PROVIDER'] || DEFAULT_REGION)
454
+ # return the endpoint if it does not map to a default endpoint, allowing
455
+ # the endpoint to be a full hostname instead of a region.
456
+ DEFAULT_SERVICE_ENDPOINTS[service.to_s][endpoint] || endpoint
457
+ end
458
+
459
+ def tag_instance(credentials, instance, name)
460
+ ec2 = new_client(credentials)
461
+ safely do
462
+ ec2.create_tag(instance.id, 'name', name)
463
+ end
464
+ end
465
+
466
+ def untag_instance(credentials, instance_id)
467
+ ec2 = new_client(credentials)
468
+ safely do
469
+ ec2.delete_tag(instance_id, 'name')
470
+ end
471
+ end
472
+
473
+ def delete_unused_tags(credentials, inst_ids)
474
+ ec2 = new_client(credentials)
475
+ tags = []
476
+ safely do
477
+ tags = ec2.describe_tags('Filter.1.Name' => 'resource-type', 'Filter.1.Value' => 'instance')
478
+ tags.collect! { |t| t[:aws_resource_id] }
479
+ inst_ids.each do |inst_id|
480
+ unless tags.include?(inst_id)
481
+ ec2.delete_tag(inst_id, 'name')
482
+ end
483
+ end
410
484
  end
411
485
  end
412
486
 
@@ -425,6 +499,16 @@ module Deltacloud
425
499
  )
426
500
  end
427
501
 
502
+ def convert_object(s3_object)
503
+ Blob.new(
504
+ :id => s3_object.name,
505
+ :bucket => s3_object.bucket.name.to_s,
506
+ :content_length => s3_object.headers['content-length'],
507
+ :content_type => s3_object.headers['content-type'],
508
+ :last_modified => s3_object.last_modified
509
+ )
510
+ end
511
+
428
512
  def convert_realm(realm)
429
513
  Realm.new(
430
514
  :id => realm[:zone_name],