deltacloud-core 0.1.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. data/DISCLAIMER +8 -0
  2. data/{COPYING → LICENSE} +0 -0
  3. data/NOTICE +13 -0
  4. data/Rakefile +50 -51
  5. data/bin/deltacloudd +8 -1
  6. data/config.ru +0 -2
  7. data/config/drivers.yaml +48 -0
  8. data/deltacloud-core.gemspec +75 -0
  9. data/deltacloud.rb +3 -2
  10. data/lib/deltacloud/backend_capability.rb +15 -3
  11. data/lib/deltacloud/base_driver.rb +0 -2
  12. data/lib/deltacloud/base_driver/base_driver.rb +85 -89
  13. data/lib/deltacloud/base_driver/features.rb +61 -7
  14. data/lib/deltacloud/base_driver/mock_driver.rb +42 -43
  15. data/lib/deltacloud/core_ext.rb +18 -0
  16. data/lib/deltacloud/core_ext/integer.rb +31 -0
  17. data/lib/deltacloud/core_ext/string.rb +50 -0
  18. data/lib/deltacloud/drivers/azure/azure_driver.rb +71 -22
  19. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +641 -584
  20. data/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb +0 -2
  21. data/lib/deltacloud/drivers/eucalyptus/eucalyptus_driver.rb +167 -0
  22. data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +39 -1
  23. data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +41 -25
  24. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob1.yml +6 -3
  25. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob2.yml +6 -3
  26. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob3.yml +4 -2
  27. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob4.yml +5 -2
  28. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob5.yml +4 -2
  29. data/lib/deltacloud/drivers/mock/data/instances/inst0.yml +1 -0
  30. data/lib/deltacloud/drivers/mock/data/instances/inst1.yml +1 -0
  31. data/lib/deltacloud/drivers/mock/data/instances/inst2.yml +1 -0
  32. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol1.yml +1 -0
  33. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol2.yml +1 -0
  34. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol3.yml +1 -0
  35. data/lib/deltacloud/drivers/mock/mock_driver.rb +138 -30
  36. data/lib/deltacloud/drivers/opennebula/cloud_client.rb +13 -15
  37. data/lib/deltacloud/drivers/opennebula/occi_client.rb +13 -15
  38. data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +13 -15
  39. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +224 -113
  40. data/lib/deltacloud/drivers/rhevm/rhevm_client.rb +332 -0
  41. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +221 -170
  42. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +0 -1
  43. data/lib/deltacloud/drivers/sbc/sbc_client.rb +247 -0
  44. data/lib/deltacloud/drivers/sbc/sbc_driver.rb +297 -0
  45. data/lib/deltacloud/drivers/terremark/terremark_driver.rb +0 -2
  46. data/lib/deltacloud/hardware_profile.rb +1 -3
  47. data/lib/deltacloud/helpers.rb +0 -2
  48. data/lib/deltacloud/helpers/application_helper.rb +86 -12
  49. data/lib/deltacloud/helpers/blob_stream.rb +19 -2
  50. data/lib/deltacloud/helpers/conversion_helper.rb +0 -2
  51. data/lib/deltacloud/helpers/hardware_profiles_helper.rb +0 -2
  52. data/lib/deltacloud/method_serializer.rb +0 -2
  53. data/lib/deltacloud/models/base_model.rb +0 -2
  54. data/lib/deltacloud/models/blob.rb +1 -2
  55. data/lib/deltacloud/models/bucket.rb +0 -2
  56. data/lib/deltacloud/models/image.rb +0 -2
  57. data/lib/deltacloud/models/instance.rb +19 -2
  58. data/lib/deltacloud/models/instance_profile.rb +4 -2
  59. data/lib/deltacloud/models/key.rb +0 -2
  60. data/lib/deltacloud/models/load_balancer.rb +0 -2
  61. data/lib/deltacloud/models/realm.rb +0 -2
  62. data/lib/deltacloud/models/storage_snapshot.rb +0 -2
  63. data/lib/deltacloud/models/storage_volume.rb +4 -2
  64. data/lib/deltacloud/runner.rb +132 -0
  65. data/lib/deltacloud/state_machine.rb +0 -2
  66. data/lib/deltacloud/validation.rb +9 -7
  67. data/lib/drivers.rb +36 -48
  68. data/lib/sinatra/accept_media_types.rb +26 -0
  69. data/lib/sinatra/lazy_auth.rb +16 -0
  70. data/lib/sinatra/rabbit.rb +112 -54
  71. data/lib/sinatra/rack_driver_select.rb +50 -16
  72. data/lib/sinatra/rack_etag.rb +79 -0
  73. data/lib/sinatra/rack_matrix_params.rb +84 -0
  74. data/lib/sinatra/rack_runtime.rb +47 -0
  75. data/lib/sinatra/static_assets.rb +16 -0
  76. data/lib/sinatra/url_for.rb +31 -4
  77. data/public/favicon.ico +0 -0
  78. data/public/images/bread-bg.png +0 -0
  79. data/public/images/error.png +0 -0
  80. data/public/images/pending.png +0 -0
  81. data/public/images/running.png +0 -0
  82. data/public/images/stopped.png +0 -0
  83. data/public/javascripts/application.js +35 -0
  84. data/public/stylesheets/compiled/application.css +59 -5
  85. data/public/stylesheets/compiled/screen.css +1 -1
  86. data/server.rb +293 -29
  87. data/support/fedora/deltacloud-core +78 -0
  88. data/support/fedora/deltacloud-core.spec +143 -0
  89. data/support/fedora/deltacloudd +78 -18
  90. data/support/fedora/rubygem-deltacloud-core.spec +76 -40
  91. data/tests/common.rb +172 -0
  92. data/tests/drivers/mock/api_test.rb +133 -0
  93. data/tests/drivers/mock/hardware_profiles_test.rb +134 -0
  94. data/tests/drivers/mock/images_test.rb +126 -0
  95. data/tests/drivers/mock/instance_states_test.rb +71 -0
  96. data/tests/drivers/mock/instances_test.rb +236 -0
  97. data/tests/drivers/mock/realms_test.rb +93 -0
  98. data/tests/drivers/mock/setup.rb +3 -0
  99. data/tests/drivers/mock/url_for_test.rb +67 -0
  100. data/tests/drivers/rackspace/api_test.rb +41 -0
  101. data/tests/drivers/rackspace/hardware_profiles_test.rb +53 -0
  102. data/tests/drivers/rackspace/images_test.rb +40 -0
  103. data/tests/drivers/rackspace/instances_test.rb +161 -0
  104. data/tests/drivers/rackspace/realms_test.rb +36 -0
  105. data/tests/drivers/rackspace/setup.rb +14 -0
  106. data/tests/drivers/rhevm/api_test.rb +39 -0
  107. data/tests/drivers/rhevm/hardware_profiles_test.rb +53 -0
  108. data/tests/drivers/rhevm/images_test.rb +42 -0
  109. data/tests/drivers/rhevm/instances_test.rb +179 -0
  110. data/tests/drivers/rhevm/realms_test.rb +35 -0
  111. data/tests/drivers/rhevm/setup.rb +14 -0
  112. data/tests/rabbit_test.rb +52 -0
  113. data/views/api/show.html.haml +2 -5
  114. data/views/blobs/new.html.haml +17 -1
  115. data/views/blobs/show.html.haml +6 -0
  116. data/views/blobs/show.xml.haml +5 -1
  117. data/views/buckets/index.html.haml +1 -12
  118. data/views/buckets/index.xml.haml +3 -5
  119. data/views/docs/operation.html.haml +23 -11
  120. data/views/drivers/index.html.haml +15 -0
  121. data/views/drivers/index.xml.haml +7 -0
  122. data/views/drivers/show.html.haml +20 -0
  123. data/views/drivers/show.xml.haml +7 -0
  124. data/views/error.html.haml +31 -0
  125. data/views/errors/auth_exception.xml.haml +2 -1
  126. data/views/errors/backend_capability_failure.xml.haml +2 -1
  127. data/views/errors/backend_error.html.haml +3 -0
  128. data/views/errors/backend_error.xml.haml +2 -2
  129. data/views/errors/validation_failure.xml.haml +3 -2
  130. data/views/images/index.html.haml +1 -6
  131. data/views/images/index.xml.haml +2 -0
  132. data/views/images/new.html.haml +14 -0
  133. data/views/images/show.xml.haml +2 -0
  134. data/views/instances/index.html.haml +8 -6
  135. data/views/instances/index.xml.haml +4 -0
  136. data/views/instances/new.html.haml +40 -11
  137. data/views/instances/run.html.haml +9 -0
  138. data/views/instances/run.xml.haml +7 -0
  139. data/views/instances/run_command.html.haml +16 -0
  140. data/views/instances/show.html.haml +14 -0
  141. data/views/instances/show.xml.haml +12 -4
  142. data/views/layout.html.haml +7 -2
  143. data/views/load_balancers/index.html.haml +1 -1
  144. data/views/load_balancers/new.html.haml +2 -2
  145. data/views/load_balancers/show.html.haml +1 -1
  146. data/views/storage_snapshots/index.html.haml +3 -0
  147. data/views/storage_snapshots/new.html.haml +9 -0
  148. data/views/storage_volumes/attach.html.haml +20 -0
  149. data/views/storage_volumes/index.html.haml +16 -1
  150. data/views/storage_volumes/index.xml.haml +1 -10
  151. data/views/storage_volumes/new.html.haml +17 -0
  152. data/views/storage_volumes/show.html.haml +8 -0
  153. data/views/storage_volumes/show.xml.haml +25 -3
  154. metadata +197 -127
  155. data/lib/deltacloud/drivers/rackspace/rackspace_client.rb +0 -130
  156. data/parse.rb +0 -7
  157. data/test.rb +0 -3
  158. data/views/api/drivers.xml.haml +0 -6
@@ -1,6 +1,3 @@
1
- #
2
- # Copyright (C) 2009, 2010 Red Hat, Inc.
3
- #
4
1
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
2
  # contributor license agreements. See the NOTICE file distributed with
6
3
  # this work for additional information regarding copyright ownership. The
@@ -15,660 +12,720 @@
15
12
  # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
13
  # License for the specific language governing permissions and limitations
17
14
  # under the License.
18
-
15
+ #
19
16
 
20
17
  require 'deltacloud/base_driver'
21
- require 'active_support'
22
- require 'AWS'
23
- require 'right_aws'
18
+ require 'aws'
19
+
20
+ class Instance
21
+ attr_accessor :keyname
22
+ attr_accessor :authn_error
23
+
24
+ def authn_feature_failed?
25
+ return true unless authn_error.nil?
26
+ end
27
+
28
+ end
24
29
 
25
30
  module Deltacloud
26
31
  module Drivers
27
32
  module EC2
28
- class EC2Driver < Deltacloud::BaseDriver
33
+ class EC2Driver < Deltacloud::BaseDriver
29
34
 
30
- def supported_collections
31
- DEFAULT_COLLECTIONS + [ :keys, :buckets, :load_balancers ]
32
- end
35
+ def supported_collections
36
+ DEFAULT_COLLECTIONS + [ :keys, :buckets, :load_balancers ]
37
+ end
33
38
 
34
- feature :instances, :user_data
35
- feature :instances, :authentication_key
36
- feature :instances, :security_group
37
- feature :images, :owner_id
38
- feature :buckets, :bucket_location
39
- feature :instances, :register_to_load_balancer
40
-
41
- define_hardware_profile('m1.small') do
42
- cpu 1
43
- memory 1.7 * 1024
44
- storage 160
45
- architecture 'i386'
46
- end
39
+ feature :instances, :user_data
40
+ feature :instances, :authentication_key
41
+ feature :instances, :security_group
42
+ feature :instances, :instance_count
43
+ feature :images, :owner_id
44
+ feature :buckets, :bucket_location
45
+ feature :instances, :register_to_load_balancer
46
+
47
+ DEFAULT_REGION = 'us-east-1'
48
+
49
+ define_hardware_profile('t1.micro') do
50
+ cpu 1
51
+ memory 0.63 * 1024
52
+ storage 160
53
+ architecture 'i386'
54
+ end
47
55
 
48
- define_hardware_profile('m1.large') do
49
- cpu 4
50
- memory 7.5 * 1024
51
- storage 850
52
- architecture 'x86_64'
53
- end
56
+ define_hardware_profile('m1.small') do
57
+ cpu 1
58
+ memory 1.7 * 1024
59
+ storage 160
60
+ architecture 'i386'
61
+ end
54
62
 
55
- define_hardware_profile('m1.xlarge') do
56
- cpu 8
57
- memory 15 * 1024
58
- storage 1690
59
- architecture 'x86_64'
60
- end
63
+ define_hardware_profile('m1.large') do
64
+ cpu 4
65
+ memory 7.5 * 1024
66
+ storage 850
67
+ architecture 'x86_64'
68
+ end
61
69
 
62
- define_hardware_profile('c1.medium') do
63
- cpu 5
64
- memory 1.7 * 1024
65
- storage 350
66
- architecture 'i386'
67
- end
70
+ define_hardware_profile('m1.xlarge') do
71
+ cpu 8
72
+ memory 15 * 1024
73
+ storage 1690
74
+ architecture 'x86_64'
75
+ end
68
76
 
69
- define_hardware_profile('c1.xlarge') do
70
- cpu 20
71
- memory 7 * 1024
72
- storage 1690
73
- architecture 'x86_64'
74
- end
77
+ define_hardware_profile('c1.medium') do
78
+ cpu 5
79
+ memory 1.7 * 1024
80
+ storage 350
81
+ architecture 'i386'
82
+ end
75
83
 
76
- define_hardware_profile('m2.xlarge') do
77
- cpu 6.5
78
- memory 17.1 * 1024
79
- storage 420
80
- architecture 'x86_64'
81
- end
84
+ define_hardware_profile('c1.xlarge') do
85
+ cpu 20
86
+ memory 7 * 1024
87
+ storage 1690
88
+ architecture 'x86_64'
89
+ end
82
90
 
83
- define_hardware_profile('m2.2xlarge') do
84
- cpu 13
85
- memory 34.2 * 1024
86
- storage 850
87
- architecture 'x86_64'
88
- end
91
+ define_hardware_profile('m2.xlarge') do
92
+ cpu 6.5
93
+ memory 17.1 * 1024
94
+ storage 420
95
+ architecture 'x86_64'
96
+ end
89
97
 
90
- define_hardware_profile('m2.4xlarge') do
91
- cpu 26
92
- memory 68.4 * 1024
93
- storage 1690
94
- architecture 'x86_64'
95
- end
98
+ define_hardware_profile('m2.2xlarge') do
99
+ cpu 13
100
+ memory 34.2 * 1024
101
+ storage 850
102
+ architecture 'x86_64'
103
+ end
96
104
 
97
- define_instance_states do
98
- start.to( :pending ) .automatically
99
- pending.to( :running ) .automatically
100
- pending.to( :stopping ) .on( :stop )
101
- pending.to( :stopped ) .automatically
102
- stopped.to( :running ) .on( :start )
103
- running.to( :running ) .on( :reboot )
104
- running.to( :stopping ) .on( :stop )
105
- shutting_down.to( :stopped ) .automatically
106
- stopped.to( :finish ) .automatically
107
- end
105
+ define_hardware_profile('m2.4xlarge') do
106
+ cpu 26
107
+ memory 68.4 * 1024
108
+ storage 1690
109
+ architecture 'x86_64'
110
+ end
108
111
 
109
- #
110
- # Images
111
- #
112
-
113
- def images(credentials, opts={} )
114
- ec2 = new_client(credentials)
115
- img_arr = []
116
- # if we know the image_id, we don't want to limit by owner_id, since this
117
- # will exclude public images
118
- if (opts and opts[:id])
119
- config = { :image_id => opts[:id] }
120
- else
121
- config = { :owner_id => "amazon" }
122
- config.merge!({ :owner_id => opts[:owner_id] }) if opts and opts[:owner_id]
123
- end
124
- safely do
125
- image_set = ec2.describe_images(config).imagesSet
126
- unless image_set.nil?
127
- image_set.item.each do |image|
128
- img_arr << convert_image(image)
112
+ define_instance_states do
113
+ start.to( :pending ) .automatically
114
+ pending.to( :running ) .automatically
115
+ pending.to( :stopping ) .on( :stop )
116
+ pending.to( :stopped ) .automatically
117
+ stopped.to( :running ) .on( :start )
118
+ running.to( :running ) .on( :reboot )
119
+ running.to( :stopping ) .on( :stop )
120
+ shutting_down.to( :stopped ) .automatically
121
+ stopped.to( :finish ) .automatically
129
122
  end
130
- end
131
- end
132
- img_arr = filter_on( img_arr, :architecture, opts )
133
- img_arr.sort_by{|e| [e.owner_id, e.name]}
134
- end
135
123
 
136
- #
137
- # Realms
138
- #
124
+ # We do not allow users to set the endpoint through environment
125
+ # variables. That that would work is an implementation detail.
126
+ ENV.delete("EC2_URL")
127
+ ENV.delete("S3_URL")
128
+ ENV.delete("ELB_URL")
129
+
130
+ def images(credentials, opts={})
131
+ ec2 = new_client(credentials)
132
+ img_arr = []
133
+ opts ||= {}
134
+ if opts[:id]
135
+ safely do
136
+ img_arr = ec2.describe_images(opts[:id]).collect do |image|
137
+ convert_image(image)
138
+ end
139
+ end
140
+ return img_arr
141
+ end
142
+ owner_id = opts[:owner_id] || default_image_owner
143
+ safely do
144
+ img_arr = ec2.describe_images_by_owner(owner_id, default_image_type).collect do |image|
145
+ convert_image(image)
146
+ end
147
+ end
148
+ img_arr = filter_on( img_arr, :architecture, opts )
149
+ img_arr.sort_by { |e| [e.owner_id, e.name] }
150
+ end
139
151
 
140
- def realms(credentials, opts=nil)
141
- ec2 = new_client(credentials)
142
- realms = []
143
- safely do
144
- ec2.describe_availability_zones.availabilityZoneInfo.item.each do |ec2_realm|
145
- realms << convert_realm( ec2_realm )
146
- end
147
- end
148
- realms
149
- end
152
+ def realms(credentials, opts={})
153
+ ec2 = new_client(credentials)
154
+ zone_id = opts ? opts[:id] : nil
155
+ safely do
156
+ return ec2.describe_availability_zones(zone_id).collect do |realm|
157
+ convert_realm(realm)
158
+ end
159
+ end
160
+ end
150
161
 
151
- #
152
- # Instances
153
- #
154
- def instances(credentials, opts=nil)
155
- ec2 = new_client(credentials)
156
- instances = []
157
- safely do
158
- param = opts.nil? ? nil : opts[:id]
159
- ec2_instances = ec2.describe_instances.reservationSet
160
- return [] unless ec2_instances
161
- ec2_instances.item.each do |item|
162
- item.instancesSet.item.each do |ec2_instance|
163
- instances << convert_instance( ec2_instance, item.ownerId )
162
+ def create_image(credentials, opts={})
163
+ ec2 = new_client(credentials)
164
+ instance = instance(credentials, :id => opts[:id])
165
+ safely do
166
+ new_image_id = ec2.create_image(instance.id, opts[:name], opts[:description])
167
+ image(credentials, :id => new_image_id)
168
+ end
164
169
  end
165
- end
166
- end
167
- instances = filter_on( instances, :id, opts )
168
- instances = filter_on( instances, :state, opts )
169
- instances
170
- end
171
170
 
171
+ def instances(credentials, opts={})
172
+ ec2 = new_client(credentials)
173
+ inst_arr = []
174
+ safely do
175
+ inst_arr = ec2.describe_instances.collect do |instance|
176
+ convert_instance(instance) if instance
177
+ end.flatten
178
+ if tagging?
179
+ tags = ec2.describe_tags('Filter.1.Name' => 'resource-type',
180
+ 'Filter.1.Value' => 'instance')
181
+ inst_arr.each do |inst|
182
+ name_tag = tags.select do |t|
183
+ (t[:aws_resource_id] == inst.id) and t[:aws_key] == 'name'
184
+ end
185
+ unless name_tag.empty?
186
+ inst.name = name_tag.first[:aws_value]
187
+ end
188
+ end
189
+ delete_unused_tags(credentials, inst_arr.collect {|inst| inst.id})
190
+ end
191
+ end
192
+ inst_arr = filter_on( inst_arr, :id, opts )
193
+ filter_on( inst_arr, :state, opts )
194
+ end
172
195
 
173
- def create_instance(credentials, image_id, opts)
174
- ec2 = new_client( credentials )
175
- realm_id = opts[:realm_id]
176
- safely do
177
- image = image(credentials, :id => image_id )
178
- hwp = find_hardware_profile(credentials, opts[:hwp_id], image.id)
179
- ec2_instances = ec2.run_instances(
180
- :image_id => image.id,
181
- :user_data => opts[:user_data],
182
- :key_name => opts[:keyname],
183
- :availability_zone => realm_id,
184
- :monitoring_enabled => true,
185
- :instance_type => hwp.name,
186
- :disable_api_termination => false,
187
- :instance_initiated_shutdown_behavior => 'terminate',
188
- :security_group => opts[:security_group]
189
- )
190
- new_instance = convert_instance( ec2_instances.instancesSet.item.first, 'pending' )
191
- if opts[:load_balancer_id] and opts[:load_balancer_id]!=""
192
- elb = new_client(credentials, :elb)
193
- elb.register_instances_with_load_balancer({
194
- :instances => [new_instance.id],
195
- :load_balancer_name => opts[:load_balancer_id]
196
- })
197
- end
198
- return new_instance
199
- end
200
- end
196
+ def create_instance(credentials, image_id, opts={})
197
+ ec2 = new_client(credentials)
198
+ instance_options = {}
199
+ instance_options.merge!(:user_data => opts[:user_data]) if opts[:user_data]
200
+ instance_options.merge!(:key_name => opts[:keyname]) if opts[:keyname]
201
+ instance_options.merge!(:availability_zone => opts[:realm_id]) if opts[:realm_id]
202
+ instance_options.merge!(:instance_type => opts[:hwp_id]) if opts[:hwp_id] && opts[:hwp_id].length > 0
203
+ instance_options.merge!(:group_ids => opts[:security_group]) if opts[:security_group]
204
+ instance_options.merge!(
205
+ :min_count => opts[:instance_count],
206
+ :max_count => opts[:instance_count]
207
+ ) if opts[:instance_count] and opts[:instance_count].length!=0
208
+ safely do
209
+ new_instance = convert_instance(ec2.launch_instances(image_id, instance_options).first)
210
+ # TODO: Rework this to use client_id for name instead of tag
211
+ # Tags should be keept as an optional feature
212
+ tag_instance(credentials, new_instance, opts[:name])
213
+ # Register Instance to Load Balancer if load_balancer_id is set.
214
+ # This parameter is a feature parameter
215
+ if opts[:load_balancer_id]
216
+ lb = lb_register_instance(credentials,
217
+ {'id' => opts[:load_balancer_id],
218
+ 'instance_id' => new_instance.id})
219
+ end
220
+ new_instance
221
+ end
222
+ end
201
223
 
202
- def generate_instance(ec2, id, backup)
203
- begin
204
- this_instance = ec2.describe_instances( :instance_id => id ).reservationSet.item.first.instancesSet.item.first
205
- convert_instance(this_instance, this_instance.ownerId)
206
- rescue Exception => e
207
- puts "WARNING: ignored error during instance refresh: #{e.message}"
208
- # at this point, the action has succeeded but our follow-up
209
- # "describe_instances" failed for some reason. Create a simple Instance
210
- # object with only the ID and new state in place
211
- state = convert_state(backup.instancesSet.item.first.currentState.name)
212
- Instance.new( {
213
- :id => id,
214
- :state => state,
215
- :actions => instance_actions_for( state ),
216
- } )
217
- end
218
- end
224
+ def run_on_instance(credentials, opts={})
225
+ target = instance(credentials, :id => opts[:id])
226
+ param = {}
227
+ param[:credentials] = {
228
+ :username => 'root', # Default for EC2 Linux instances
229
+ }
230
+ param[:port] = opts[:port] || '22'
231
+ param[:ip] = target.public_addresses
232
+ param[:private_key] = (opts[:private_key].length > 1) ? opts[:private_key] : nil
233
+ safely do
234
+ Deltacloud::Runner.execute(opts[:cmd], param)
235
+ end
236
+ end
237
+
238
+ def reboot_instance(credentials, instance_id)
239
+ ec2 = new_client(credentials)
240
+ if ec2.reboot_instances([instance_id])
241
+ instance(credentials, instance_id)
242
+ else
243
+ raise Deltacloud::BackendError.new(500, "Instance", "Instance reboot failed", "")
244
+ end
245
+ end
219
246
 
220
- def reboot_instance(credentials, id)
221
- ec2 = new_client(credentials)
222
- backup = ec2.reboot_instances( :instance_id => id )
247
+ def destroy_instance(credentials, instance_id)
248
+ ec2 = new_client(credentials)
249
+ instance_id = instance_id
250
+ if ec2.terminate_instances([instance_id])
251
+ untag_instance(credentials, instance_id)
252
+ instance(credentials, instance_id)
253
+ else
254
+ raise Deltacloud::BackendError.new(500, "Instance", "Instance cannot be terminated", "")
255
+ end
256
+ end
223
257
 
224
- generate_instance(ec2, id, backup)
225
- end
258
+ alias :stop_instance :destroy_instance
226
259
 
227
- def stop_instance(credentials, id)
228
- ec2 = new_client(credentials)
229
- backup = ec2.terminate_instances( :instance_id => id )
260
+ def keys(credentials, opts={})
261
+ ec2 = new_client(credentials)
262
+ opts ||= {}
263
+ safely do
264
+ ec2.describe_key_pairs(opts[:id] || nil).collect do |key|
265
+ convert_key(key)
266
+ end
267
+ end
268
+ end
230
269
 
231
- generate_instance(ec2, id, backup)
232
- end
270
+ def create_key(credentials, opts={})
271
+ ec2 = new_client(credentials)
272
+ safely do
273
+ convert_key(ec2.create_key_pair(opts[:key_name]))
274
+ end
275
+ end
233
276
 
234
- def destroy_instance(credentials, id)
235
- ec2 = new_client(credentials)
236
- backup = ec2.terminate_instances( :instance_id => id )
277
+ def destroy_key(credentials, opts={})
278
+ ec2 = new_client(credentials)
279
+ original_key = key(credentials, opts)
280
+ safely do
281
+ ec2.delete_key_pair(original_key.id)
282
+ original_key= original_key.state = "DELETED"
283
+ end
284
+ original_key
285
+ end
237
286
 
238
- generate_instance(ec2, id, backup)
239
- end
287
+ def load_balancer(credentials, opts={})
288
+ load_balancers(credentials, {
289
+ :names => [opts[:id]]
290
+ }).first
291
+ end
240
292
 
241
- #
242
- # Storage Volumes
243
- #
293
+ def load_balancers(credentials, opts=nil)
294
+ ec2 = new_client( credentials, :elb )
295
+ result = []
296
+ safely do
297
+ loadbalancers = ec2.describe_load_balancers(opts || {})
298
+ loadbalancers.each do |loadbalancer|
299
+ result << convert_load_balancer(credentials, loadbalancer)
300
+ end
301
+ end
302
+ return result
303
+ end
244
304
 
245
- def storage_volumes(credentials, opts=nil)
246
- ec2 = new_client( credentials )
247
- volumes = []
248
- safely do
249
- if (opts)
250
- ec2.describe_volumes(:volume_id => opts[:id]).volumeSet.item.each do |ec2_volume|
251
- volumes << convert_volume( ec2_volume )
305
+ def create_load_balancer(credentials, opts={})
306
+ ec2 = new_client( credentials, :elb )
307
+ safely do
308
+ ec2.create_load_balancer(opts['name'], [opts['realm_id']],
309
+ [{:load_balancer_port => opts['listener_balancer_port'],
310
+ :instance_port => opts['listener_instance_port'],
311
+ :protocol => opts['listener_protocol']}]
312
+ )
313
+ return load_balancer(credentials, opts['name'])
314
+ end
252
315
  end
253
- else
254
- ec2_volumes = ec2.describe_volumes.volumeSet
255
- return [] unless ec2_volumes
256
- ec2_volumes.item.each do |ec2_volume|
257
- volumes << convert_volume( ec2_volume )
316
+
317
+ def destroy_load_balancer(credentials, id)
318
+ ec2 = new_client( credentials, :elb )
319
+ safely do
320
+ ec2.delete_load_balancer(id)
321
+ end
258
322
  end
259
- end
260
- end
261
- volumes
262
- end
263
323
 
264
- #
265
- # Storage Snapshots
266
- #
324
+ def lb_register_instance(credentials, opts={})
325
+ ec2 = new_client( credentials, :elb)
326
+ safely do
327
+ ec2.register_instances_with_load_balancer(opts['id'], [opts['instance_id']])
328
+ load_balancer(credentials, :id => opts[:id])
329
+ end
330
+ end
267
331
 
268
- def storage_snapshots(credentials, opts=nil)
269
- ec2 = new_client( credentials )
270
- snapshots = []
271
- safely do
272
- if (opts)
273
- ec2.describe_snapshots(:owner => 'self', :snapshot_id => opts[:id]).snapshotSet.item.each do |ec2_snapshot|
274
- snapshots << convert_snapshot( ec2_snapshot )
332
+ def lb_unregister_instance(credentials, opts={})
333
+ ec2 = new_client( credentials, :elb)
334
+ safely do
335
+ ec2.deregister_instances_from_load_balancer(opts['id'], [opts['instance_id']])
336
+ load_balancer(credentials, :id => opts['id'])
337
+ end
275
338
  end
276
- else
277
- ec2_snapshots = ec2.describe_snapshots(:owner => 'self').snapshotSet
278
- return [] unless ec2_snapshots
279
- ec2_snapshots.item.each do |ec2_snapshot|
280
- snapshots << convert_snapshot( ec2_snapshot )
339
+
340
+ def buckets(credentials, opts={})
341
+ buckets = []
342
+ safely do
343
+ s3_client = new_client(credentials, :s3)
344
+ unless (opts[:id].nil?)
345
+ bucket = s3_client.bucket(opts[:id])
346
+ buckets << convert_bucket(bucket)
347
+ else
348
+ bucket_list = s3_client.buckets
349
+ bucket_list.each do |current|
350
+ buckets << Bucket.new({:name => current.name, :id => current.name})
351
+ end #bucket_list.each
352
+ end #if
353
+ end #safely
354
+ filter_on(buckets, :id, opts)
281
355
  end
282
- end
283
- end
284
- snapshots
285
- end
286
356
 
287
- def key(credentials, opts=nil)
288
- keys(credentials, opts).first
289
- end
357
+ def create_bucket(credentials, name, opts={})
358
+ bucket = nil
359
+ safely do
360
+ s3_client = new_client(credentials, :s3)
361
+ bucket_location = opts['location']
362
+ if bucket_location
363
+ bucket = Aws::S3::Bucket.create(s3_client, name, true, nil, :location => bucket_location)
364
+ else
365
+ bucket = Aws::S3::Bucket.create(s3_client, name, true)
366
+ end
367
+ end
368
+ convert_bucket(bucket)
369
+ end
290
370
 
291
- def keys(credentials, opts=nil)
292
- ec2 = new_client( credentials )
293
- opts[:key_name] = opts[:id] if opts and opts[:id]
294
- keypairs = ec2.describe_keypairs(opts || {})
295
- result = []
296
- safely do
297
- keypairs.keySet.item.each do |keypair|
298
- result << convert_key(keypair)
299
- end if keypairs.keySet
300
- end
301
- result
302
- end
371
+ def delete_bucket(credentials, name, opts={})
372
+ s3_client = new_client(credentials, :s3)
373
+ safely do
374
+ s3_client.interface.delete_bucket(name)
375
+ end
376
+ end
303
377
 
304
- def create_key(credentials, opts={})
305
- key = Key.new
306
- ec2 = new_client( credentials )
307
- safely do
308
- key = convert_key(ec2.create_keypair(opts))
309
- end
310
- return key
311
- end
378
+ def blobs(credentials, opts = {})
379
+ s3_client = new_client(credentials, :s3)
380
+ blobs = []
381
+ safely do
382
+ s3_bucket = s3_client.bucket(opts['bucket'])
383
+ s3_bucket.keys({}, true).each do |s3_object|
384
+ blobs << convert_object(s3_object)
385
+ end
386
+ end
387
+ blobs = filter_on(blobs, :id, opts)
388
+ blobs
389
+ end
312
390
 
313
- def destroy_key(credentials, opts={})
314
- safely do
315
- ec2 = new_client( credentials )
316
- ec2.delete_keypair(opts)
317
- end
318
- end
391
+ #--
392
+ # Create Blob
393
+ #--
394
+ def create_blob(credentials, bucket_id, blob_id, data = nil, opts = {})
395
+ s3_client = new_client(credentials, :s3)
396
+ #data is a construct with the temporary file created by server @.tempfile
397
+ #also file[:type] will give us the content-type
398
+ res = nil
399
+ # File stream needs to be reopened in binary mode for whatever reason
400
+ file = File::open(data[:tempfile].path, 'rb')
401
+ #insert ec2-specific header for user metadata ... x-amz-meta-KEY = VALUE
402
+ opts.gsub_keys('HTTP_X_Deltacloud_Blobmeta_', 'x-amz-meta-')
403
+ opts["Content-Type"] = data[:type]
404
+ safely do
405
+ res = s3_client.interface.put(bucket_id,
406
+ blob_id,
407
+ file,
408
+ opts)
409
+ end
410
+ #create a new Blob object and return that
411
+ Blob.new( { :id => blob_id,
412
+ :bucket => bucket_id,
413
+ :content_length => data[:tempfile].length,
414
+ :content_type => data[:type],
415
+ :last_modified => '',
416
+ :user_metadata => opts.select{|k,v| k.match(/^x-amz-meta-/i)}
417
+ }
418
+ )
419
+ end
319
420
 
320
- def valid_credentials?(credentials)
321
- client = new_client(credentials)
322
- # FIXME: We need to do this call to determine if
323
- # EC2 is working with given credentials. There is no
324
- # other way to check, if given credentials are valid or not.
325
- realms = client.describe_availability_zones rescue false
326
- return realms ? true : false
327
- end
421
+ #--
422
+ # Delete Blob
423
+ #--
424
+ def delete_blob(credentials, bucket_id, blob_id, opts={})
425
+ s3_client = new_client(credentials, :s3)
426
+ safely do
427
+ s3_client.interface.delete(bucket_id, blob_id)
428
+ end
429
+ end
328
430
 
329
- #--
330
- # Buckets
331
- #-- get a list of your buckets from the s3 service
332
- def buckets(credentials, opts)
333
- buckets = []
334
- safely do
335
- s3_client = s3_client(credentials)
336
- bucket_list = s3_client.buckets
337
- bucket_list.each do |current|
338
- buckets << convert_bucket(current)
339
- end
340
- end
341
- buckets = filter_on(buckets, :id, opts)
342
- buckets
343
- end
344
431
 
345
- #--
346
- # Create bucket
347
- #--
348
- #valid values for bucket location: 'EU'|'us-west1'|'ap-southeast-1' - if you
349
- #don't specify a location then by default buckets are created in 'us-east'
350
- #[but if you *do* specify 'us-east' things blow up]
351
- def create_bucket(credentials, name, opts={})
352
- bucket = nil
353
- safely do
354
- begin
355
- s3_client = s3_client(credentials)
356
- bucket_location = opts['location']
357
- if bucket_location
358
- bucket = RightAws::S3::Bucket.create(s3_client, name, true, nil, :location => bucket_location)
359
- else
360
- bucket = RightAws::S3::Bucket.create(s3_client, name, true)
361
- end #if
362
- rescue RightAws::AwsError => e
363
- raise e unless e.message =~ /BucketAlreadyExists/
364
- raise Deltacloud::BackendError.new(409, e.class.to_s, e.message, e.backtrace)
365
- end #begin
366
- end #do
367
- convert_bucket(bucket)
368
- end
432
+ def blob_data(credentials, bucket_id, blob_id, opts={})
433
+ s3_client = new_client(credentials, :s3)
434
+ safely do
435
+ s3_client.interface.get(bucket_id, blob_id) do |chunk|
436
+ yield chunk
437
+ end
438
+ end
439
+ end
369
440
 
370
- #--
371
- # Delete_bucket
372
- #--
373
- def delete_bucket(credentials, name, opts={})
374
- s3_client = s3_client(credentials)
375
- safely do
376
- s3_client.interface.delete_bucket(name)
377
- end
378
- end
441
+ def storage_volumes(credentials, opts={})
442
+ ec2 = new_client( credentials )
443
+ volume_list = (opts and opts[:id]) ? opts[:id] : nil
444
+ safely do
445
+ ec2.describe_volumes(volume_list).collect do |volume|
446
+ convert_volume(volume)
447
+ end
448
+ end
449
+ end
379
450
 
380
- #--
381
- # Blobs
382
- #--
383
- def blobs(credentials, opts = nil)
384
- s3_client = s3_client(credentials)
385
- blobs = []
386
- safely do
387
- s3_bucket = s3_client.bucket(opts['bucket'])
388
- s3_bucket.keys({}, true).each do |s3_object|
389
- blobs << convert_object(s3_object)
390
- end
391
- end
392
- blobs = filter_on(blobs, :id, opts)
393
- blobs
394
- end
451
+ def create_storage_volume(credentials, opts=nil)
452
+ ec2 = new_client(credentials)
453
+ opts ||= {}
454
+ opts[:snapshot_id] ||= ""
455
+ opts[:capacity] ||= "1"
456
+ opts[:realm_id] ||= realms(credentials).first.id
457
+ safely do
458
+ convert_volume(ec2.create_volume(opts[:snapshot_id], opts[:capacity], opts[:realm_id]))
459
+ end
460
+ end
395
461
 
396
- #--
397
- # Blob data
398
- #--
399
- def blob_data(credentials, bucket_id, blob_id, opts)
400
- s3_client = s3_client(credentials)
401
- safely do
402
- s3_client.interface.get(bucket_id, blob_id) do |chunk|
403
- yield chunk
404
- end
405
- end
406
- end
462
+ def destroy_storage_volume(credentials, opts={})
463
+ ec2 = new_client(credentials)
464
+ safely do
465
+ unless ec2.delete_volume(opts[:id])
466
+ raise Deltacloud::BackendError.new(500, "StorageVolume", "Cannot delete storage volume")
467
+ end
468
+ storage_volume(credentials, opts[:id])
469
+ end
470
+ end
407
471
 
408
- #--
409
- # Create Blob
410
- #--
411
- def create_blob(credentials, bucket_id, blob_id, data = nil, opts = nil)
412
- s3_client = s3_client(credentials)
413
- #data is a construct with the temporary file created by server @.tempfile
414
- #also file[:type] will give us the content-type
415
- safely do
416
- res = s3_client.interface.put(bucket_id, blob_id, data[:tempfile], {"Content-Type" => data[:type]})
417
- #create a new Blob object and return that
418
- Blob.new( { :id => blob_id,
419
- :bucket => bucket_id,
420
- :content_length => data[:tempfile].length,
421
- :content_type => data[:type],
422
- :last_modified => ''
423
- }
424
- )
425
- end
426
- end
472
+ def attach_storage_volume(credentials, opts={})
473
+ ec2 = new_client(credentials)
474
+ safely do
475
+ convert_volume(ec2.attach_volume(opts[:id], opts[:instance_id], opts[:device]))
476
+ end
477
+ end
427
478
 
428
- #--
429
- # Delete Blob
430
- #--
431
- def delete_blob(credentials, bucket_id, blob_id, opts=nil)
432
- s3_client = s3_client(credentials)
433
- safely do
434
- s3_client.interface.delete(bucket_id, blob_id)
435
- end
436
- end
479
+ def detach_storage_volume(credentials, opts={})
480
+ ec2 = new_client(credentials)
481
+ safely do
482
+ convert_volume(ec2.detach_volume(opts[:id], opts[:instance_id], opts[:device], true))
483
+ end
484
+ end
437
485
 
438
- def load_balancer(credentials, opts={})
439
- load_balancers(credentials, {
440
- :load_balancer_names => [opts[:id]]
441
- }).first
442
- end
486
+ def storage_snapshots(credentials, opts={})
487
+ ec2 = new_client(credentials)
488
+ snapshot_list = (opts and opts[:id]) ? opts[:id] : []
489
+ safely do
490
+ ec2.describe_snapshots(snapshot_list).collect do |snapshot|
491
+ convert_snapshot(snapshot)
492
+ end
493
+ end
494
+ end
443
495
 
444
- def load_balancers(credentials, opts=nil)
445
- ec2 = new_client( credentials, :elb )
446
- result = []
447
- safely do
448
- loadbalancers = ec2.describe_load_balancers(opts || {})
449
- return [] unless loadbalancers.DescribeLoadBalancersResult.LoadBalancerDescriptions
450
- loadbalancers.DescribeLoadBalancersResult.LoadBalancerDescriptions.member.each do |loadbalancer|
451
- result << convert_load_balancer(credentials, loadbalancer)
452
- end
453
- end
454
- return result
455
- end
496
+ def create_storage_snapshot(credentials, opts={})
497
+ ec2 = new_client(credentials)
498
+ safely do
499
+ convert_snapshot(ec2.try_create_snapshot(opts[:volume_id]))
500
+ end
501
+ end
456
502
 
457
- def create_load_balancer(credentials, opts={})
458
- ec2 = new_client( credentials, :elb )
459
- safely do
460
- ec2.create_load_balancer({
461
- :load_balancer_name => opts['name'],
462
- # TODO: Add possibility to push more listeners/realms in one request
463
- # Something like 'Hash' in 'Array' parameter
464
- :availability_zones => [opts['realm_id']],
465
- :listeners => [{
466
- :protocol => opts['listener_protocol'],
467
- :load_balancer_port => opts['listener_balancer_port'],
468
- :instance_port => opts['listener_instance_port']
469
- }]
470
- })
471
- return load_balancer(credentials, opts['name'])
472
- end
473
- end
503
+ def destroy_storage_snapshot(credentials, opts={})
504
+ ec2 = new_client(credentials)
505
+ safely do
506
+ unless ec2.delete_snapshot(opts[:id])
507
+ raise Deltacloud::BackendError.new(500, "StorageSnapshot", "Cannot destroy this snapshot")
508
+ end
509
+ end
510
+ end
474
511
 
475
- def destroy_load_balancer(credentials, id)
476
- ec2 = new_client( credentials, :elb )
477
- safely do
478
- ec2.delete_load_balancer({
479
- :load_balancer_name => id
480
- })
481
- end
482
- end
512
+ def valid_credentials?(credentials)
513
+ retval = true
514
+ begin
515
+ realms(credentials)
516
+ rescue Deltacloud::BackendError
517
+ retval = false
518
+ end
519
+ retval
520
+ end
483
521
 
484
- def lb_register_instance(credentials, opts={})
485
- ec2 = new_client( credentials, :elb)
486
- safely do
487
- ec2.register_instances_with_load_balancer(:instances => [opts[:instance_id]],
488
- :load_balancer_name => opts[:id])
489
- load_balancer(credentials, :id => opts[:id])
490
- end
491
- end
522
+ private
492
523
 
493
- def lb_unregister_instance(credentials, opts={})
494
- ec2 = new_client( credentials, :elb)
495
- safely do
496
- ec2.deregister_instances_from_load_balancer(:instances => [opts[:instance_id]],
497
- :load_balancer_name => opts[:id])
498
- load_balancer(credentials, :id => opts[:id])
499
- end
500
- end
524
+ def new_client(credentials, type = :ec2)
525
+ klass = case type
526
+ when :elb then Aws::Elb
527
+ when :ec2 then Aws::Ec2
528
+ when :s3 then Aws::S3
529
+ end
530
+ klass.new(credentials.user, credentials.password, {:server => endpoint_for_service(type), :connection_mode => :per_thread})
531
+ end
501
532
 
502
- private
503
-
504
- def new_client(credentials, provider_type = :ec2)
505
- opts = {
506
- :access_key_id => credentials.user,
507
- :secret_access_key => credentials.password
508
- }
509
- opts[:server] = ENV['DCLOUD_EC2_URL'] if ENV['DCLOUD_EC2_URL']
510
- safely do
511
- case provider_type
512
- when :ec2
513
- AWS::EC2::Base.new(opts)
514
- when :elb
515
- AWS::ELB::Base.new(opts)
516
- end
517
- end
518
- end
533
+ def default_image_owner
534
+ "amazon"
535
+ end
519
536
 
520
- def convert_load_balancer(credentials, loadbalancer)
521
- balancer_realms = loadbalancer.AvailabilityZones.member.collect do |m|
522
- realm(credentials, m)
523
- end
524
- balancer = LoadBalancer.new({
525
- :id => loadbalancer['LoadBalancerName'],
526
- :created_at => loadbalancer['CreatedTime'],
527
- :public_addresses => [loadbalancer['DNSName']],
528
- :realms => balancer_realms
529
- })
530
- balancer.listeners = []
531
- balancer.instances = []
532
- loadbalancer.Listeners.member.each do |listener|
533
- balancer.add_listener({
534
- :protocol => listener['Protocol'],
535
- :load_balancer_port => listener['LoadBalancerPort'],
536
- :instance_port => listener['InstancePort']
537
- })
538
- end
539
- loadbalancer.Instances.member.each do |instance|
540
- balancer.instances << instances(credentials, :id => instance['InstanceId']).first
541
- end if loadbalancer.Instances
542
- balancer
543
- end
537
+ def default_image_type
538
+ "machine"
539
+ end
544
540
 
541
+ def tagging?
542
+ true
543
+ end
545
544
 
546
- def convert_key(key)
547
- Key.new({
548
- :id => key['keyName'],
549
- :fingerprint => key['keyFingerprint'],
550
- :credential_type => :key,
551
- :pem_rsa_key => key['keyMaterial']
552
- })
553
- end
545
+ def endpoint_for_service(service)
546
+ endpoint = (Thread.current[:provider] || ENV['API_PROVIDER'] || DEFAULT_REGION)
547
+ # return the endpoint if it does not map to a default endpoint, allowing
548
+ # the endpoint to be a full hostname instead of a region.
549
+ Deltacloud::Drivers::driver_config[:ec2][:entrypoints][service.to_s][endpoint] || endpoint
550
+ end
554
551
 
555
- def convert_image(ec2_image)
556
- Image.new( {
557
- :id=>ec2_image['imageId'],
558
- :name=>ec2_image['name'] || ec2_image['imageId'],
559
- :description=>ec2_image['description'] || ec2_image['imageLocation'] || '',
560
- :owner_id=>ec2_image['imageOwnerId'],
561
- :architecture=>ec2_image['architecture'],
562
- } )
563
- end
552
+ def tag_instance(credentials, instance, name)
553
+ if name
554
+ ec2 = new_client(credentials)
555
+ safely do
556
+ ec2.create_tag(instance.id, 'name', name)
557
+ end
558
+ end
559
+ end
564
560
 
565
- def convert_realm(ec2_realm)
566
- Realm.new( {
567
- :id=>ec2_realm['zoneName'],
568
- :name=>ec2_realm['zoneName'],
569
- :limit=>ec2_realm['zoneState'].eql?('available') ? :unlimited : 0,
570
- :state=>ec2_realm['zoneState'].upcase,
571
- } )
572
- end
561
+ def untag_instance(credentials, instance_id)
562
+ ec2 = new_client(credentials)
563
+ safely do
564
+ ec2.delete_tag(instance_id, 'name')
565
+ end
566
+ end
573
567
 
574
- def convert_state(ec2_state)
575
- case ec2_state
576
- when "terminated"
577
- "STOPPED"
578
- when "stopped"
579
- "STOPPED"
580
- when "running"
581
- "RUNNING"
582
- when "pending"
583
- "PENDING"
584
- when "shutting-down"
585
- "STOPPED"
586
- end
587
- end
568
+ def delete_unused_tags(credentials, inst_ids)
569
+ ec2 = new_client(credentials)
570
+ tags = []
571
+ safely do
572
+ tags = ec2.describe_tags('Filter.1.Name' => 'resource-type', 'Filter.1.Value' => 'instance')
573
+ tags.collect! { |t| t[:aws_resource_id] }
574
+ inst_ids.each do |inst_id|
575
+ unless tags.include?(inst_id)
576
+ ec2.delete_tag(inst_id, 'name')
577
+ end
578
+ end
579
+ end
580
+ end
581
+
582
+ def convert_bucket(s3_bucket)
583
+ #get blob list:
584
+ blob_list = []
585
+ s3_bucket.keys.each do |s3_object|
586
+ blob_list << s3_object.name
587
+ end
588
+ #can use AWS::S3::Owner.current.display_name or current.id
589
+ Bucket.new(
590
+ :id => s3_bucket.name,
591
+ :name => s3_bucket.name,
592
+ :size => blob_list.length,
593
+ :blob_list => blob_list
594
+ )
595
+ end
588
596
 
589
- def convert_instance(ec2_instance, owner_id)
590
- state = convert_state(ec2_instance['instanceState']['name'])
591
- realm_id = ec2_instance['placement']['availabilityZone']
592
- (realm_id = nil ) if ( realm_id == '' )
593
- hwp_name = ec2_instance['instanceType']
594
- instance = Instance.new( {
595
- :id=>ec2_instance['instanceId'],
596
- :name => ec2_instance['imageId'],
597
- :state=>state,
598
- :image_id=>ec2_instance['imageId'],
599
- :owner_id=>owner_id,
600
- :realm_id=>realm_id,
601
- :public_addresses=>( ec2_instance['dnsName'] == '' ? [] : [ec2_instance['dnsName']] ),
602
- :private_addresses=>( ec2_instance['privateDnsName'] == '' ? [] : [ec2_instance['privateDnsName']] ),
603
- :instance_profile =>InstanceProfile.new(hwp_name),
604
- :actions=>instance_actions_for( state ),
605
- :keyname => ec2_instance['keyName'],
606
- :launch_time => ec2_instance['launchTime']
607
- } )
608
- instance.authn_error = "Key not set for instance" unless ec2_instance['keyName']
609
- return instance
610
- end
597
+ def convert_object(s3_object)
598
+ Blob.new(
599
+ :id => s3_object.name,
600
+ :bucket => s3_object.bucket.name.to_s,
601
+ :content_length => s3_object.headers['content-length'],
602
+ :content_type => s3_object.headers['content-type'],
603
+ :last_modified => s3_object.last_modified,
604
+ :user_metadata => s3_object.meta_headers
605
+ )
606
+ end
611
607
 
612
- def convert_volume(ec2_volume)
613
- StorageVolume.new( {
614
- :id=>ec2_volume['volumeId'],
615
- :created=>ec2_volume['createTime'],
616
- :state=>ec2_volume['status'].upcase,
617
- :capacity=>ec2_volume['size'],
618
- :instance_id=>ec2_volume['snapshotId'],
619
- :device=>ec2_volume['attachmentSet'],
620
- } )
621
- end
608
+ def convert_realm(realm)
609
+ Realm.new(
610
+ :id => realm[:zone_name],
611
+ :name => realm[:zone_name],
612
+ :state => realm[:zone_state],
613
+ :limit => realm[:zone_state].eql?('available') ? :unlimited : 0
614
+ )
615
+ end
622
616
 
623
- def convert_snapshot(ec2_snapshot)
624
- StorageSnapshot.new( {
625
- :id=>ec2_snapshot['snapshotId'],
626
- :state=>ec2_snapshot['status'].upcase,
627
- :storage_volume_id=>ec2_snapshot['volumeId'],
628
- :created=>ec2_snapshot['startTime'],
629
- } )
630
- end
617
+ def convert_image(image)
618
+ # There is not support for 'name' for now
619
+ Image.new(
620
+ :id => image[:aws_id],
621
+ :name => image[:aws_name] || image[:aws_id],
622
+ :description => image[:aws_description] || image[:aws_location],
623
+ :owner_id => image[:aws_owner],
624
+ :architecture => image[:aws_architecture],
625
+ :state => image[:state]
626
+ )
627
+ end
631
628
 
632
- def s3_client(credentials)
633
- safely do
634
- s3_client = RightAws::S3.new(credentials.user, credentials.password)
635
- end
636
- end
629
+ def convert_instance(instance)
630
+ can_create_image = 'ebs'.eql?(instance[:root_device_type]) and 'RUNNING'.eql?(convert_state(instance[:aws_state]))
631
+ Instance.new(
632
+ :id => instance[:aws_instance_id],
633
+ :name => instance[:aws_image_id],
634
+ :state => convert_state(instance[:aws_state]),
635
+ :image_id => instance[:aws_image_id],
636
+ :owner_id => instance[:aws_owner],
637
+ :actions => instance_actions_for(convert_state(instance[:aws_state])),
638
+ :key_name => instance[:ssh_key_name],
639
+ :launch_time => instance[:aws_launch_time],
640
+ :instance_profile => InstanceProfile.new(instance[:aws_instance_type]),
641
+ :realm_id => instance[:aws_availability_zone],
642
+ :private_addresses => instance[:private_dns_name],
643
+ :public_addresses => instance[:dns_name],
644
+ :create_image => can_create_image
645
+ )
646
+ end
637
647
 
638
- def convert_bucket(s3_bucket)
639
- #get blob list:
640
- blob_list = []
641
- s3_bucket.keys.each do |s3_object|
642
- blob_list << s3_object.name
643
- end
644
- #can use AWS::S3::Owner.current.display_name or current.id
645
- Bucket.new( { :id => s3_bucket.name,
646
- :name => s3_bucket.name,
647
- :size => s3_bucket.keys.length,
648
- :blob_list => blob_list
649
- }
650
- )
651
- end
648
+ def convert_key(key)
649
+ Key.new(
650
+ :id => key[:aws_key_name],
651
+ :fingerprint => key[:aws_fingerprint],
652
+ :credential_type => :key,
653
+ :pem_rsa_key => key[:aws_material],
654
+ :state => "AVAILABLE"
655
+ )
656
+ end
652
657
 
653
- def convert_object(s3_object)
654
- Blob.new({ :id => s3_object.name,
655
- :bucket => s3_object.bucket.name.to_s,
656
- :content_length => s3_object.size,
657
- :content_type => s3_object.content_type,
658
- :last_modified => s3_object.last_modified
659
- })
660
- end
658
+ def convert_volume(volume)
659
+ StorageVolume.new(
660
+ :id => volume[:aws_id],
661
+ :created => volume[:aws_created_at],
662
+ :state => volume[:aws_status] ? volume[:aws_status].upcase : 'unknown',
663
+ :capacity => volume[:aws_size],
664
+ :instance_id => volume[:aws_instance_id],
665
+ :realm_id => volume[:zone],
666
+ :device => volume[:aws_device],
667
+ # TODO: the available actions should be tied to the current
668
+ # volume state
669
+ :actions => [:attach, :detach, :destroy]
670
+ )
671
+ end
661
672
 
662
- def catched_exceptions_list
663
- {
664
- :auth => [ AWS::AuthFailure ],
665
- :error => [ RightAws::AwsError ],
666
- :glob => [ /.*AWS::(\w+)/ ]
667
- }
668
- end
673
+ def convert_snapshot(snapshot)
674
+ StorageSnapshot.new(
675
+ :id => snapshot[:aws_id],
676
+ :state => snapshot[:aws_status],
677
+ :storage_volume_id => snapshot[:aws_volume_id],
678
+ :created => snapshot[:aws_started_at]
679
+ )
680
+ end
669
681
 
670
- end
682
+ def convert_load_balancer(credentials, loadbalancer)
683
+ puts loadbalancer.inspect
684
+ realms = []
685
+ balancer_realms = loadbalancer[:availability_zones].each do |zone|
686
+ realms << realm(credentials, zone)
687
+ end
688
+ balancer = LoadBalancer.new({
689
+ :id => loadbalancer[:name],
690
+ :created_at => loadbalancer[:created_time],
691
+ :public_addresses => [loadbalancer[:dns_name]],
692
+ :realms => realms
693
+ })
694
+ balancer.listeners = []
695
+ balancer.instances = []
696
+ loadbalancer[:listeners].each do |listener|
697
+ balancer.add_listener(listener)
698
+ end
699
+ loadbalancer[:instances].each do |instance|
700
+ balancer.instances << instance(credentials, :id => instance[:id])
701
+ end
702
+ balancer
703
+ end
671
704
 
705
+ def convert_state(ec2_state)
706
+ case ec2_state
707
+ when "terminated"
708
+ "STOPPED"
709
+ when "stopped"
710
+ "STOPPED"
711
+ when "running"
712
+ "RUNNING"
713
+ when "pending"
714
+ "PENDING"
715
+ when "shutting-down"
716
+ "STOPPED"
717
+ end
718
+ end
719
+
720
+ def catched_exceptions_list
721
+ {
722
+ :auth => [ /AuthFailure/ ],
723
+ :error => [ /Aws::AwsError/, /Error/ ],
724
+ :glob => [ /AWS::(\w+)/, /Deltacloud::Runner::(\w+)/ ]
725
+ }
726
+ end
727
+
728
+ end
672
729
  end
673
730
  end
674
731
  end