deltacloud-core 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/config.ru CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'sinatra'
2
2
  require 'rubygems'
3
- require 'server.rb'
4
3
 
4
+ require 'server.rb'
5
5
  run Sinatra::Application
@@ -9,6 +9,7 @@ require 'deltacloud/models/base_model'
9
9
  require 'deltacloud/models/realm'
10
10
  require 'deltacloud/models/image'
11
11
  require 'deltacloud/models/instance'
12
+ require 'deltacloud/models/key'
12
13
  require 'deltacloud/models/instance_profile'
13
14
  require 'deltacloud/models/storage_snapshot'
14
15
  require 'deltacloud/models/storage_volume'
@@ -31,6 +31,16 @@ module Deltacloud
31
31
  end
32
32
  end
33
33
 
34
+ class BackendFeatureUnsupported < StandardError
35
+ attr_reader :code, :cause, :details
36
+ def initialize(code, cause, message, details)
37
+ super(message)
38
+ @code = code
39
+ @cause = cause
40
+ @details = details
41
+ end
42
+ end
43
+
34
44
  class BaseDriver
35
45
 
36
46
  def self.define_hardware_profile(name,&block)
@@ -195,6 +205,25 @@ module Deltacloud
195
205
  return false
196
206
  end
197
207
 
208
+ def catched_exceptions_list
209
+ { :error => [], :auth => [], :glob => [] }
210
+ end
211
+
212
+ def safely(&block)
213
+ begin
214
+ block.call
215
+ rescue *catched_exceptions_list[:error] => e
216
+ raise Deltacloud::BackendError.new(502, e.class.to_s, e.message, e.backtrace)
217
+ rescue *catched_exceptions_list[:auth] => e
218
+ raise Deltacloud::AuthException.new
219
+ rescue => e
220
+ catched_exceptions_list[:glob].each do |ex|
221
+ raise Deltacloud::BackendError.new(502, e.class.to_s, e.message, e.backtrace) if e.class.name =~ ex
222
+ end
223
+ raise e
224
+ end
225
+ end
226
+
198
227
  end
199
228
 
200
229
  end
@@ -120,6 +120,13 @@ module Deltacloud
120
120
  #
121
121
  # Declaration of optional features
122
122
  #
123
+ declare_feature :images, :owner_id do
124
+ description "Filter images using owner id"
125
+ operation :index do
126
+ param :owner_id, :string, :optional, nil, "Owner ID"
127
+ end
128
+ end
129
+
123
130
  declare_feature :instances, :user_name do
124
131
  description "Accept a user-defined name on instance creation"
125
132
  operation :create do
@@ -11,10 +11,13 @@ module Mock
11
11
  [
12
12
  :describe_images,
13
13
  :describe_availability_zones,
14
+ :describe_keypairs,
15
+ :create_keypair,
14
16
  :run_instances,
15
17
  :describe_instances,
16
18
  :reboot_instances,
17
- :terminate_instances
19
+ :terminate_instances,
20
+ :delete_keypair
18
21
  ]
19
22
  end
20
23
 
@@ -35,8 +35,13 @@ module Deltacloud
35
35
  module EC2
36
36
  class EC2Driver < Deltacloud::BaseDriver
37
37
 
38
+ def supported_collections
39
+ DEFAULT_COLLECTIONS + [ :keys ]
40
+ end
41
+
38
42
  feature :instances, :user_data
39
43
  feature :instances, :authentication_key
44
+ feature :images, :owner_id
40
45
 
41
46
  define_hardware_profile('m1.small') do
42
47
  cpu 1
@@ -170,40 +175,60 @@ class EC2Driver < Deltacloud::BaseDriver
170
175
  def create_instance(credentials, image_id, opts)
171
176
  ec2 = new_client( credentials )
172
177
  realm_id = opts[:realm_id]
173
- image = image(credentials, :id => image_id )
174
- hwp = find_hardware_profile(credentials, opts[:hwp_id], image.id)
175
- ec2_instances = ec2.run_instances(
176
- :image_id => image.id,
177
- :user_data => opts[:user_data],
178
- :key_name => opts[:keyname],
179
- :availability_zone => realm_id,
180
- :monitoring_enabled => true,
181
- :instance_type => hwp.name,
182
- :disable_api_termination => false,
183
- :instance_initiated_shutdown_behavior => 'terminate'
184
- )
185
- convert_instance( ec2_instances.instancesSet.item.first, 'pending' )
178
+ safely do
179
+ image = image(credentials, :id => image_id )
180
+ hwp = find_hardware_profile(credentials, opts[:hwp_id], image.id)
181
+ ec2_instances = ec2.run_instances(
182
+ :image_id => image.id,
183
+ :user_data => opts[:user_data],
184
+ :key_name => opts[:keyname],
185
+ :availability_zone => realm_id,
186
+ :monitoring_enabled => true,
187
+ :instance_type => hwp.name,
188
+ :disable_api_termination => false,
189
+ :instance_initiated_shutdown_behavior => 'terminate'
190
+ )
191
+ return convert_instance( ec2_instances.instancesSet.item.first, 'pending' )
192
+ end
193
+ end
194
+
195
+ def generate_instance(ec2, id, backup)
196
+ begin
197
+ this_instance = ec2.describe_instances( :instance_id => id ).reservationSet.item.first.instancesSet.item.first
198
+ convert_instance(this_instance, this_instance.ownerId)
199
+ rescue Exception => e
200
+ puts "WARNING: ignored error during instance refresh: #{e.message}"
201
+ # at this point, the action has succeeded but our follow-up
202
+ # "describe_instances" failed for some reason. Create a simple Instance
203
+ # object with only the ID and new state in place
204
+ state = backup.instancesSet.item.first.currentState.name
205
+ Instance.new( {
206
+ :id => id,
207
+ :state => state,
208
+ :actions => instance_actions_for( state ),
209
+ } )
210
+ end
186
211
  end
187
212
 
188
213
  def reboot_instance(credentials, id)
189
214
  ec2 = new_client(credentials)
190
- safely do
191
- ec2.reboot_instances( :instance_id => id )
192
- end
215
+ backup = ec2.reboot_instances( :instance_id => id )
216
+
217
+ generate_instance(ec2, id, backup)
193
218
  end
194
219
 
195
220
  def stop_instance(credentials, id)
196
221
  ec2 = new_client(credentials)
197
- safely do
198
- ec2.terminate_instances( :instance_id => id )
199
- end
222
+ backup = ec2.terminate_instances( :instance_id => id )
223
+
224
+ generate_instance(ec2, id, backup)
200
225
  end
201
226
 
202
227
  def destroy_instance(credentials, id)
203
228
  ec2 = new_client(credentials)
204
- safely do
205
- ec2.terminate_instances( :instance_id => id )
206
- end
229
+ backup = ec2.terminate_instances( :instance_id => id )
230
+
231
+ generate_instance(ec2, id, backup)
207
232
  end
208
233
 
209
234
  #
@@ -252,6 +277,39 @@ class EC2Driver < Deltacloud::BaseDriver
252
277
  snapshots
253
278
  end
254
279
 
280
+ def key(credentials, opts=nil)
281
+ keys(credentials, opts).first
282
+ end
283
+
284
+ def keys(credentials, opts=nil)
285
+ ec2 = new_client( credentials )
286
+ opts[:key_name] = opts[:id] if opts and opts[:id]
287
+ keypairs = ec2.describe_keypairs(opts || {})
288
+ result = []
289
+ safely do
290
+ keypairs.keySet.item.each do |keypair|
291
+ result << convert_key(keypair)
292
+ end
293
+ end
294
+ result
295
+ end
296
+
297
+ def create_key(credentials, opts={})
298
+ key = Key.new
299
+ ec2 = new_client( credentials )
300
+ safely do
301
+ key = convert_key(ec2.create_keypair(opts))
302
+ end
303
+ return key
304
+ end
305
+
306
+ def destroy_key(credentials, opts={})
307
+ safely do
308
+ ec2 = new_client( credentials )
309
+ ec2.delete_keypair(opts)
310
+ end
311
+ end
312
+
255
313
  private
256
314
 
257
315
  def new_client(credentials)
@@ -260,7 +318,18 @@ class EC2Driver < Deltacloud::BaseDriver
260
318
  :secret_access_key => credentials.password
261
319
  }
262
320
  opts[:server] = ENV['DCLOUD_EC2_URL'] if ENV['DCLOUD_EC2_URL']
263
- AWS::EC2::Base.new(opts)
321
+ safely do
322
+ AWS::EC2::Base.new(opts)
323
+ end
324
+ end
325
+
326
+ def convert_key(key)
327
+ Key.new({
328
+ :id => key['keyName'],
329
+ :fingerprint => key['keyFingerprint'],
330
+ :credential_type => :key,
331
+ :pem_rsa_key => key['keyMaterial']
332
+ })
264
333
  end
265
334
 
266
335
  def convert_image(ec2_image)
@@ -326,14 +395,12 @@ class EC2Driver < Deltacloud::BaseDriver
326
395
  } )
327
396
  end
328
397
 
329
- def safely(&block)
330
- begin
331
- block.call
332
- rescue AWS::AuthFailure => e
333
- raise Deltacloud::AuthException.new
334
- rescue Exception => e
335
- puts "ERROR: #{e.message}\n#{e.backtrace.join("\n")}"
336
- end
398
+ def catched_exceptions_list
399
+ {
400
+ :auth => [ AWS::AuthFailure ],
401
+ :error => [],
402
+ :glob => [ /AWS::(\w+)/ ]
403
+ }
337
404
  end
338
405
 
339
406
  end
@@ -44,20 +44,8 @@ class GogridDriver < Deltacloud::BaseDriver
44
44
  end
45
45
 
46
46
  def supported_collections
47
- DEFAULT_COLLECTIONS.reject { |c| [ :storage_volumes, :storage_snapshots ].include?(c) }
48
- end
49
-
50
- # The only valid option for flavors is server RAM for now
51
- def flavors(credentials, opts=nil)
52
- flavors = []
53
- safely do
54
- flavors=new_client(credentials).request('common/lookup/list', { 'lookup' => 'server.ram' })['list'].collect do |flavor|
55
- convert_flavor(flavor)
56
- end
57
- end
58
- flavors = filter_on( flavors, :id, opts )
59
- flavors = filter_on( flavors, :architecture, opts )
60
- flavors
47
+ DEFAULT_COLLECTIONS.reject! { |c| [ :storage_volumes, :storage_snapshots ].include?(c) }
48
+ DEFAULT_COLLECTIONS + [ :keys ]
61
49
  end
62
50
 
63
51
  def images(credentials, opts=nil)
@@ -188,6 +176,19 @@ class GogridDriver < Deltacloud::BaseDriver
188
176
  end
189
177
  end
190
178
 
179
+ def key(credentials, opts=nil)
180
+ keys(credentials, opts).first
181
+ end
182
+
183
+ def keys(credentials, opts=nil)
184
+ gogrid = new_client( credentials )
185
+ creds = []
186
+ gogrid.request('support/password/list')['list'].each do |password|
187
+ creds << convert_key(password)
188
+ end
189
+ return creds
190
+ end
191
+
191
192
  define_instance_states do
192
193
  start.to( :pending ) .automatically
193
194
  pending.to( :running ) .automatically
@@ -219,6 +220,15 @@ class GogridDriver < Deltacloud::BaseDriver
219
220
  return login_data
220
221
  end
221
222
 
223
+ def convert_key(password)
224
+ Key.new({
225
+ :id => password['id'],
226
+ :username => password['username'],
227
+ :password => password['password'],
228
+ :credential_type => :password
229
+ })
230
+ end
231
+
222
232
  def convert_image(gg_image, owner_id=nil)
223
233
  Image.new( {
224
234
  :id=>gg_image['id'],
@@ -237,15 +247,6 @@ class GogridDriver < Deltacloud::BaseDriver
237
247
  end
238
248
  end
239
249
 
240
- def convert_flavor(flavor)
241
- Flavor.new(
242
- :id => flavor['id'],
243
- :architecture => 'x86',
244
- :memory => flavor['name'].tr('G', ''),
245
- :storage => '1'
246
- )
247
- end
248
-
249
250
  def convert_realm(realm)
250
251
  Realm.new(
251
252
  :id => realm['id'],
@@ -279,7 +280,6 @@ class GogridDriver < Deltacloud::BaseDriver
279
280
  :id => instance['name'],
280
281
  :owner_id => owner_id,
281
282
  :image_id => instance['image']['id'],
282
- :flavor_id => instance['ram']['id'],
283
283
  :instance_profile => prof,
284
284
  :name => instance['name'],
285
285
  :realm_id => instance['type']['id'],
@@ -316,7 +316,7 @@ class GogridDriver < Deltacloud::BaseDriver
316
316
  begin
317
317
  block.call
318
318
  rescue Exception => e
319
- puts "ERROR: #{e.message}"
319
+ raise Deltacloud::BackendError.new(500, e.class.to_s, e.message, e.backtrace)
320
320
  end
321
321
  end
322
322
 
@@ -29,11 +29,13 @@ class RackspaceDriver < Deltacloud::BaseDriver
29
29
 
30
30
  def hardware_profiles(credentials, opts = nil)
31
31
  racks = new_client( credentials )
32
- results = racks.list_flavors.map do |flav|
33
- HardwareProfile.new(flav["id"].to_s) do
34
- architecture 'x86_64'
35
- memory flav["ram"].to_i
36
- storage flav["disk"].to_i
32
+ safely do
33
+ results = racks.list_flavors.map do |flav|
34
+ HardwareProfile.new(flav["id"].to_s) do
35
+ architecture 'x86_64'
36
+ memory flav["ram"].to_i
37
+ storage flav["disk"].to_i
38
+ end
37
39
  end
38
40
  end
39
41
  filter_hardware_profiles(results, opts)
@@ -41,14 +43,16 @@ class RackspaceDriver < Deltacloud::BaseDriver
41
43
 
42
44
  def images(credentials, opts=nil)
43
45
  racks = new_client( credentials )
44
- results = racks.list_images.map do |img|
45
- Image.new( {
46
- :id=>img["id"].to_s,
47
- :name=>img["name"],
48
- :description => img["name"] + " " + img["status"] + "",
49
- :owner_id=>"root",
50
- :architecture=>'x86_64'
51
- } )
46
+ safely do
47
+ results = racks.list_images.map do |img|
48
+ Image.new( {
49
+ :id=>img["id"].to_s,
50
+ :name=>img["name"],
51
+ :description => img["name"] + " " + img["status"] + "",
52
+ :owner_id=>"root",
53
+ :architecture=>'x86_64'
54
+ } )
55
+ end
52
56
  end
53
57
  results.sort_by{|e| [e.description]}
54
58
  results = filter_on( results, :id, opts )
@@ -66,7 +70,9 @@ class RackspaceDriver < Deltacloud::BaseDriver
66
70
 
67
71
  def reboot_instance(credentials, id)
68
72
  racks = new_client(credentials)
69
- racks.reboot_server(id)
73
+ safely do
74
+ racks.reboot_server(id)
75
+ end
70
76
  end
71
77
 
72
78
  def stop_instance(credentials, id)
@@ -75,7 +81,9 @@ class RackspaceDriver < Deltacloud::BaseDriver
75
81
 
76
82
  def destroy_instance(credentials, id)
77
83
  racks = new_client(credentials)
78
- racks.delete_server(id)
84
+ safely do
85
+ racks.delete_server(id)
86
+ end
79
87
  end
80
88
 
81
89
 
@@ -88,7 +96,9 @@ class RackspaceDriver < Deltacloud::BaseDriver
88
96
  hwp_id = opts[:hwp_id] || 1
89
97
  name = Time.now.to_s
90
98
  if (opts[:name]) then name = opts[:name] end
91
- convert_srv_to_instance(racks.start_server(image_id, hwp_id, name))
99
+ safely do
100
+ return convert_srv_to_instance(racks.start_server(image_id, hwp_id, name))
101
+ end
92
102
  end
93
103
 
94
104
  #
@@ -97,12 +107,14 @@ class RackspaceDriver < Deltacloud::BaseDriver
97
107
  def instances(credentials, opts=nil)
98
108
  racks = new_client(credentials)
99
109
  instances = []
100
- if (opts.nil?)
101
- instances = racks.list_servers.map do |srv|
102
- convert_srv_to_instance(srv)
110
+ safely do
111
+ if (opts.nil?)
112
+ instances = racks.list_servers.map do |srv|
113
+ convert_srv_to_instance(srv)
114
+ end
115
+ else
116
+ instances << convert_srv_to_instance(racks.load_server_details(opts[:id]))
103
117
  end
104
- else
105
- instances << convert_srv_to_instance(racks.load_server_details(opts[:id]))
106
118
  end
107
119
  instances = filter_on( instances, :id, opts )
108
120
  instances = filter_on( instances, :state, opts )
@@ -128,7 +140,9 @@ class RackspaceDriver < Deltacloud::BaseDriver
128
140
  end
129
141
 
130
142
  def new_client(credentials)
131
- RackspaceClient.new(credentials.user, credentials.password)
143
+ safely do
144
+ return RackspaceClient.new(credentials.user, credentials.password)
145
+ end
132
146
  end
133
147
 
134
148
  define_instance_states do
@@ -144,6 +158,14 @@ class RackspaceDriver < Deltacloud::BaseDriver
144
158
  stopped.to( :finish ) .automatically
145
159
  end
146
160
 
161
+ def safely(&block)
162
+ begin
163
+ block.call
164
+ rescue Exception => e
165
+ raise Deltacloud::BackendError.new(500, e.class.to_s, e.message, e.backtrace)
166
+ end
167
+ end
168
+
147
169
  end
148
170
 
149
171
  end
@@ -29,15 +29,17 @@ class RimuHostingDriver < Deltacloud::BaseDriver
29
29
  feature :instances, :user_name
30
30
 
31
31
  def images(credentails, opts=nil)
32
- rh = RimuHostingClient.new(credentails)
33
- images = rh.list_images.map do | image |
34
- Image.new({
35
- :id => image["distro_code"].gsub(/\./,"-"),
36
- :name => image["distro_code"],
37
- :description => image["distro_description"],
38
- :owner_id => "root",
39
- :architecture => "x86"
40
- })
32
+ safely do
33
+ rh = RimuHostingClient.new(credentails)
34
+ images = rh.list_images.map do | image |
35
+ Image.new({
36
+ :id => image["distro_code"].gsub(/\./,"-"),
37
+ :name => image["distro_code"],
38
+ :description => image["distro_description"],
39
+ :owner_id => "root",
40
+ :architecture => "x86"
41
+ })
42
+ end
41
43
  end
42
44
  images.sort_by{|e| [e.description]}
43
45
  images = filter_on( images, :id, opts)
@@ -45,15 +47,17 @@ class RimuHostingDriver < Deltacloud::BaseDriver
45
47
  end
46
48
 
47
49
  def hardware_profiles(credentials, opts = nil)
48
- rh = RimuHostingClient.new(credentials)
49
- results = rh.list_plans.map do |plan|
50
- # FIXME: x86 is not a valid architecture; what is Rimu offering ?
51
- # FIXME: VPS plans offer a range of memory/storage, but that's
52
- # not contained in hte pricing_plan_infos
53
- HardwareProfile.new(plan["pricing_plan_code"]) do
54
- memory plan["minimum_memory_mb"].to_f
55
- storage plan["minimum_disk_gb"].to_i
56
- architecture "x86"
50
+ safely do
51
+ rh = RimuHostingClient.new(credentials)
52
+ results = rh.list_plans.map do |plan|
53
+ # FIXME: x86 is not a valid architecture; what is Rimu offering ?
54
+ # FIXME: VPS plans offer a range of memory/storage, but that's
55
+ # not contained in hte pricing_plan_infos
56
+ HardwareProfile.new(plan["pricing_plan_code"]) do
57
+ memory plan["minimum_memory_mb"].to_f
58
+ storage plan["minimum_disk_gb"].to_i
59
+ architecture "x86"
60
+ end
57
61
  end
58
62
  end
59
63
  filter_hardware_profiles(results, opts)
@@ -68,9 +72,11 @@ class RimuHostingDriver < Deltacloud::BaseDriver
68
72
  end
69
73
 
70
74
  def instances(credentials, opts=nil)
71
- rh = RimuHostingClient.new(credentials)
72
- instances = rh.list_nodes.map do | inst |
73
- convert_srv_to_instance(inst)
75
+ safely do
76
+ rh = RimuHostingClient.new(credentials)
77
+ instances = rh.list_nodes.map do | inst |
78
+ convert_srv_to_instance(inst)
79
+ end
74
80
  end
75
81
  instances = filter_on( instances, :id, opts)
76
82
  instances = filter_on( instances, :state, opts )
@@ -78,13 +84,17 @@ class RimuHostingDriver < Deltacloud::BaseDriver
78
84
  end
79
85
 
80
86
  def reboot_instance(credentials, id)
81
- rh = RimuHostingClient.new(credentials)
82
- rh.set_server_state(id, :RESTARTING)
87
+ safely do
88
+ rh = RimuHostingClient.new(credentials)
89
+ rh.set_server_state(id, :RESTARTING)
90
+ end
83
91
  end
84
92
 
85
93
  def start_instance(credentials, id)
86
- rh = RimuHostingClient.new(credentials)
87
- rh.set_server_state(id, :STARTED)
94
+ safely do
95
+ rh = RimuHostingClient.new(credentials)
96
+ rh.set_server_state(id, :STARTED)
97
+ end
88
98
  end
89
99
 
90
100
  def stop_instance(credentials, id)
@@ -92,8 +102,10 @@ class RimuHostingDriver < Deltacloud::BaseDriver
92
102
  end
93
103
 
94
104
  def destroy_instance(credentials, id)
95
- rh = RimuHostingClient.new(credentials)
96
- rh.delete_server(id)
105
+ safely do
106
+ rh = RimuHostingClient.new(credentials)
107
+ return rh.delete_server(id)
108
+ end
97
109
  end
98
110
 
99
111
  def create_instance(credentials, image_id, opts)
@@ -138,6 +150,14 @@ class RimuHostingDriver < Deltacloud::BaseDriver
138
150
  stopped.to( :finish ) .automatically
139
151
  end
140
152
 
153
+ def safely(&block)
154
+ begin
155
+ block.call
156
+ rescue Exception => e
157
+ raise Deltacloud::BackendError.new(500, e.class.to_s, e.message, e.backtrace)
158
+ end
159
+ end
160
+
141
161
 
142
162
  end
143
163
 
@@ -57,15 +57,17 @@ VAPP_STATE_MAP = { "0" => "PENDING", "1" => "PENDING", "2" => "STOPPED", "4"
57
57
  def images(credentials, opts=nil)
58
58
  image_list = []
59
59
  terremark_client = new_client(credentials)
60
- vdc_id = terremark_client.default_vdc_id
61
- catalogItems = terremark_client.get_catalog(vdc_id).body['CatalogItems']
62
- catalogItems.each{ |catalog_item|
63
- current_item_id = catalog_item['href'].split('/').last
64
- current_item = terremark_client.get_catalog_item(current_item_id).body['Entity']
65
- if(current_item['type'] == 'application/vnd.vmware.vcloud.vAppTemplate+xml')
66
- image_list << convert_image(current_item, credentials.user)
67
- end
68
- } #end of catalogItems.each
60
+ safely do
61
+ vdc_id = terremark_client.default_vdc_id
62
+ catalogItems = terremark_client.get_catalog(vdc_id).body['CatalogItems']
63
+ catalogItems.each{ |catalog_item|
64
+ current_item_id = catalog_item['href'].split('/').last
65
+ current_item = terremark_client.get_catalog_item(current_item_id).body['Entity']
66
+ if(current_item['type'] == 'application/vnd.vmware.vcloud.vAppTemplate+xml')
67
+ image_list << convert_image(current_item, credentials.user)
68
+ end
69
+ } #end of catalogItems.each
70
+ end
69
71
  image_list = filter_on( image_list, :id, opts )
70
72
  image_list = filter_on( image_list, :architecture, opts )
71
73
  image_list = filter_on( image_list, :owner_id, opts )
@@ -91,14 +93,16 @@ VAPP_STATE_MAP = { "0" => "PENDING", "1" => "PENDING", "2" => "STOPPED", "4"
91
93
  def instances(credentials, opts=nil)
92
94
  instances = []
93
95
  terremark_client = new_client(credentials)
94
- vdc_items = terremark_client.get_vdc(terremark_client.default_vdc_id()).body['ResourceEntities']
95
- vdc_items.each{|current_item|
96
- if(current_item['type'] == 'application/vnd.vmware.vcloud.vApp+xml')
97
- vapp_id = current_item['href'].split('/').last
98
- vapp = terremark_client.get_vapp(vapp_id)
99
- instances << convert_instance(vapp, terremark_client, credentials.user)
100
- end
101
- }#end vdc_items.each
96
+ safely do
97
+ vdc_items = terremark_client.get_vdc(terremark_client.default_vdc_id()).body['ResourceEntities']
98
+ vdc_items.each{|current_item|
99
+ if(current_item['type'] == 'application/vnd.vmware.vcloud.vApp+xml')
100
+ vapp_id = current_item['href'].split('/').last
101
+ vapp = terremark_client.get_vapp(vapp_id)
102
+ instances << convert_instance(vapp, terremark_client, credentials.user)
103
+ end
104
+ }#end vdc_items.each
105
+ end
102
106
  instances = filter_on( instances, :id, opts )
103
107
  instances
104
108
  end
@@ -135,37 +139,45 @@ VAPP_STATE_MAP = { "0" => "PENDING", "1" => "PENDING", "2" => "STOPPED", "4"
135
139
  end
136
140
  vapp_opts['cpus'] = opts[:hwp_cpu]
137
141
  vapp_opts['memory'] = opts[:hwp_memory]
138
- terremark_client = new_client(credentials)
142
+ safely do
143
+ terremark_client = new_client(credentials)
139
144
  #######
140
145
  #FIXME# what happens if there is an issue getting the new vapp id? (eg even though created succesfully)
141
146
  #######
142
- vapp_id = terremark_client.instantiate_vapp_template(name, image_id, vapp_opts).body['href'].split('/').last
143
- new_vapp = terremark_client.get_vapp(vapp_id)
144
- return convert_instance(new_vapp, terremark_client, credentials.user) #return an Instance object
147
+ vapp_id = terremark_client.instantiate_vapp_template(name, image_id, vapp_opts).body['href'].split('/').last
148
+ new_vapp = terremark_client.get_vapp(vapp_id)
149
+ return convert_instance(new_vapp, terremark_client, credentials.user) #return an Instance object
150
+ end
145
151
  end
146
152
 
147
153
  #--
148
154
  # REBOOT INSTANCE
149
155
  #--
150
156
  def reboot_instance(credentials, id)
151
- terremark_client = new_client(credentials)
152
- terremark_client.power_reset(id)
157
+ safely do
158
+ terremark_client = new_client(credentials)
159
+ return terremark_client.power_reset(id)
160
+ end
153
161
  end
154
162
 
155
163
  #--
156
164
  # START INSTANCE
157
165
  #--
158
166
  def start_instance(credentials, id)
167
+ safely do
159
168
  terremark_client = new_client(credentials)
160
- terremark_client.power_on(id)
169
+ return terremark_client.power_on(id)
170
+ end
161
171
  end
162
172
 
163
173
  #--
164
174
  # STOP INSTANCE
165
175
  #--
166
176
  def stop_instance(credentials, id)
177
+ safely do
167
178
  terremark_client = new_client(credentials)
168
- terremark_client.power_shutdown(id)
179
+ return terremark_client.power_shutdown(id)
180
+ end
169
181
  end
170
182
 
171
183
  #--
@@ -173,8 +185,10 @@ end
173
185
  #--
174
186
  #shuts down... in terremark need to do a futher delete to get rid of a vapp entirely
175
187
  def destroy_instance(credentials, id)
188
+ safely do
176
189
  terremark_client = new_client(credentials)
177
- terremark_client.delete_vapp(id)
190
+ return terremark_client.delete_vapp(id)
191
+ end
178
192
  end
179
193
 
180
194
  #--
@@ -246,14 +260,24 @@ end
246
260
  def new_client(credentials)
247
261
  #Fog constructor expecting credentials[:terremark_password] and credentials[:terremark_username]
248
262
  terremark_credentials = {:terremark_vcloud_username => "#{credentials.user}", :terremark_vcloud_password => "#{credentials.password}" }
249
- terremark_client = Fog::Terremark::Vcloud.new(terremark_credentials)
250
- vdc_id = terremark_client.default_vdc_id
263
+ safely do
264
+ terremark_client = Fog::Terremark::Vcloud.new(terremark_credentials)
265
+ vdc_id = terremark_client.default_vdc_id
266
+ end
251
267
  if (vdc_id.nil?)
252
268
  raise DeltaCloud::AuthException.new
253
269
  end
254
270
  terremark_client
255
271
  end
256
272
 
273
+ def safely(&block)
274
+ begin
275
+ block.call
276
+ rescue Exception => e
277
+ raise Deltacloud::BackendError.new(500, e.class.to_s, e.message, e.backtrace)
278
+ end
279
+ end
280
+
257
281
 
258
282
  end
259
283
 
@@ -106,4 +106,10 @@ module ApplicationHelper
106
106
  end
107
107
  end
108
108
 
109
+ def cdata(&block)
110
+ text = capture_haml(&block)
111
+ text.gsub!("\n", "\n ")
112
+ "<![CDATA[\n #{text}\n]]>"
113
+ end
114
+
109
115
  end
@@ -0,0 +1,35 @@
1
+ #
2
+ # Copyright (C) 2009 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
+
19
+ class Key < BaseModel
20
+
21
+ attr_accessor :credential_type
22
+ attr_accessor :fingerprint
23
+ attr_accessor :username
24
+ attr_accessor :password
25
+ attr_accessor :pem_rsa_key
26
+
27
+ def is_password?
28
+ true if @credential_type.eql?(:password)
29
+ end
30
+
31
+ def is_key?
32
+ true if @credential_type.eql?(:key)
33
+ end
34
+
35
+ end
@@ -1,3 +1,5 @@
1
+ require 'uri'
2
+
1
3
  module Sinatra
2
4
  module UrlForHelper
3
5
  # Construct a link to +url_fragment+, which should be given relative to
@@ -30,7 +32,8 @@ module Sinatra
30
32
  else
31
33
  raise TypeError, "Unknown url_for mode #{mode}"
32
34
  end
33
- "#{base}#{url_fragment}"
35
+ url_escape = URI.escape(url_fragment)
36
+ "#{base}#{url_escape}"
34
37
  end
35
38
 
36
39
  def root_url
data/server.rb CHANGED
@@ -100,7 +100,6 @@ END
100
100
  "owner_id" and "architecture" parameter
101
101
  END
102
102
  param :id, :string
103
- param :owner_id, :string
104
103
  param :architecture, :string, :optional
105
104
  control { filter_all(:images) }
106
105
  end
@@ -300,3 +299,56 @@ collection :storage_volumes do
300
299
  control { show(:storage_volume) }
301
300
  end
302
301
  end
302
+
303
+ get '/api/keys/new' do
304
+ respond_to do |format|
305
+ format.html { haml :"keys/new" }
306
+ end
307
+ end
308
+
309
+ collection :keys do
310
+ description "Instance authentication credentials"
311
+
312
+ operation :index do
313
+ description "List all available credentials which could be used for instance authentication"
314
+ control do
315
+ filter_all :keys
316
+ end
317
+ end
318
+
319
+ operation :show do
320
+ description "Show details about given instance credential"
321
+ param :id, :string, :required
322
+ control { show :key }
323
+ end
324
+
325
+ operation :create do
326
+ description "Create a new instance credential if backend supports this"
327
+ param :name, :string, :required
328
+ control do
329
+ unless driver.respond_to?(:create_key)
330
+ raise Deltacloud::BackendFeatureUnsupported.new('501',
331
+ 'Creating instance credentials is not supported in backend')
332
+ end
333
+ @key = driver.create_key(credentials, { :key_name => params[:name] })
334
+ respond_to do |format|
335
+ format.html { haml :"keys/show" }
336
+ format.xml { haml :"keys/show" }
337
+ end
338
+ end
339
+ end
340
+
341
+ operation :destroy do
342
+ description "Destroy given instance credential if backend supports this"
343
+ param :id, :string, :required
344
+ control do
345
+ unless driver.respond_to?(:destroy_key)
346
+ raise Deltacloud::BackendFeatureUnsupported.new('501',
347
+ 'Creating instance credentials is not supported in backend')
348
+ end
349
+ driver.destroy_key(credentials, { :key_name => params[:id]})
350
+ redirect(keys_url)
351
+ end
352
+ end
353
+
354
+ end
@@ -14,4 +14,6 @@
14
14
  %dd= @error.cause
15
15
  %di
16
16
  %dt Details
17
- %dd= @error.details
17
+ %dd
18
+ %pre
19
+ =@error.details.join("\n")
@@ -22,7 +22,7 @@
22
22
  %td
23
23
  = image.name
24
24
  %td
25
- = link_to image.owner_id, images_url( :owner_id => image.owner_id )
25
+ = link_to image.owner_id, images_url
26
26
  %td
27
27
  = image.architecture
28
28
  %td
@@ -16,7 +16,7 @@
16
16
  %td
17
17
  = link_to instance.id, instance_url( instance.id )
18
18
  %td
19
- = link_to instance.owner_id, images_url( instance.owner_id )
19
+ = link_to instance.owner_id, images_url
20
20
  %td
21
21
  = instance.name
22
22
  %td
@@ -1,30 +1,39 @@
1
1
  !!! XML
2
2
  %instance{:href => instance_url(@instance.id), :id => @instance.id}
3
- %name<
4
- =@instance.name
5
- %owner_id<
6
- =@instance.owner_id
7
- %image{:href => image_url(@instance.image_id), :id => @instance.image_id }
8
- %realm{:href => realm_url(@instance.realm_id), :id => @instance.realm_id }
9
- %state<
10
- =@instance.state
11
- - haml_tag :"hardware_profile", {:id => @instance.instance_profile.id, :href => hardware_profile_url(@instance.instance_profile.id)} do
12
- - @instance.instance_profile.overrides.each do |p, v|
13
- %property{:kind => 'fixed', :name => p, :value => v, :unit => Deltacloud::HardwareProfile::unit(p)}
14
- %actions
15
- - @instance.actions.compact.each do |instance_action|
16
- %link{:rel => instance_action, :method => instance_action_method(instance_action), :href => self.send("#{instance_action}_instance_url", @instance.id)}
3
+ - if @instance.name
4
+ %name<
5
+ =@instance.name
6
+ - if @instance.owner_id
7
+ %owner_id<
8
+ =@instance.owner_id
9
+ - if @instance.image_id
10
+ %image{:href => image_url(@instance.image_id), :id => @instance.image_id }
11
+ - if @instance.realm_id
12
+ %realm{:href => realm_url(@instance.realm_id), :id => @instance.realm_id }
13
+ - if @instance.state
14
+ %state<
15
+ =@instance.state
16
+ - if @instance.instance_profile
17
+ - haml_tag :"hardware_profile", {:id => @instance.instance_profile.id, :href => hardware_profile_url(@instance.instance_profile.id)} do
18
+ - @instance.instance_profile.overrides.each do |p, v|
19
+ %property{:kind => 'fixed', :name => p, :value => v, :unit => Deltacloud::HardwareProfile::unit(p)}
20
+ - if @instance.actions
21
+ %actions
22
+ - @instance.actions.compact.each do |instance_action|
23
+ %link{:rel => instance_action, :method => instance_action_method(instance_action), :href => self.send("#{instance_action}_instance_url", @instance.id)}
17
24
  - if @instance.instance_variables.include?("@launch_time")
18
25
  %launch_time<
19
26
  =@instance.launch_time
20
- %public_addresses
21
- - @instance.public_addresses.each do |address|
22
- %address<
23
- =address
24
- %private_addresses
25
- - @instance.private_addresses.each do |address|
26
- %address<
27
- =address
27
+ - if @instance.public_addresses
28
+ %public_addresses
29
+ - @instance.public_addresses.each do |address|
30
+ %address<
31
+ =address
32
+ - if @instance.private_addresses
33
+ %private_addresses
34
+ - @instance.private_addresses.each do |address|
35
+ %address<
36
+ =address
28
37
  - if driver_has_auth_features?
29
38
  %authentication{ :type => driver_auth_feature_name }
30
39
  - if @instance.authn_feature_failed?
@@ -0,0 +1,26 @@
1
+ %h1 Keys
2
+
3
+ %table.display
4
+ %thead
5
+ %tr
6
+ %th ID
7
+ %th Credentials details
8
+ %th Actions
9
+ %tbody
10
+ - @elements.each do |key|
11
+ %tr
12
+ %td
13
+ = link_to key.id, key_url( key.id )
14
+ %td
15
+ - if key.credential_type.eql?(:key)
16
+ = key.fingerprint
17
+ - if key.credential_type.eql?(:password)
18
+ = "#{key.username} - #{key.password}"
19
+ %td
20
+ - if driver.respond_to?(:destroy_key)
21
+ =link_to 'Destroy', destroy_key_url(key.id), :class => 'delete'
22
+ %tfoot
23
+ - if driver.respond_to?(:create_key)
24
+ %tr
25
+ %td{:colspan => 3, :style => "text-align:right;"}
26
+ =link_to 'Create &raquo;', "#{url_for('/api/keys/new')}", :class => 'button'
@@ -0,0 +1,4 @@
1
+ !!!XML
2
+ %keys
3
+ - @elements.each do |c|
4
+ = haml :'keys/show', :locals => { :@key => c, :partial => true }
@@ -0,0 +1,8 @@
1
+ %h1 New key
2
+
3
+ %form{ :action => '/api/keys', :method => :post }
4
+ %p
5
+ %label
6
+ Name:
7
+ %input{ :name => 'name', :size => 30 }/
8
+ %input{ :type => :submit, :name => "commit", :value => "create" }/
@@ -0,0 +1,22 @@
1
+ %h1
2
+ = @key.id
3
+
4
+ %dl
5
+ - if @key.is_key?
6
+ %di
7
+ %dt Fingerprint
8
+ %dd
9
+ = @key.fingerprint
10
+ - if @key.pem_rsa_key
11
+ %dt PEM key
12
+ %dd
13
+ %pre
14
+ = @key.pem_rsa_key
15
+ - if @key.is_password?
16
+ %di
17
+ %dt Username
18
+ %dd
19
+ = @key.username
20
+ %dt Password
21
+ %dd
22
+ = @key.password
@@ -0,0 +1,20 @@
1
+ - unless defined?(partial)
2
+ !!! XML
3
+ %key{ :href => key_url(@key.id), :id => @key.id, :type => "#{@key.credential_type}" }
4
+ %actions
5
+ - if driver.respond_to?(:destroy_key)
6
+ %link{ :rel => "destroy", :method => "delete", :href => destroy_key_url(@key.id)}
7
+ - if @key.is_key?
8
+ %fingerprint<
9
+ =@key.fingerprint
10
+ - unless @key.pem_rsa_key.nil?
11
+ %pem<
12
+ =cdata do
13
+ =@key.pem_rsa_key
14
+ - if @key.is_password?
15
+ %username<
16
+ =cdata do
17
+ =@key.username
18
+ %password<
19
+ =cdata do
20
+ =@key.password
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 4
9
- version: 0.0.4
8
+ - 5
9
+ version: 0.0.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - Red Hat, Inc.
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-07-28 00:00:00 +02:00
17
+ date: 2010-08-04 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -245,6 +245,7 @@ files:
245
245
  - lib/deltacloud/models/realm.rb
246
246
  - lib/deltacloud/models/storage_snapshot.rb
247
247
  - lib/deltacloud/models/storage_volume.rb
248
+ - lib/deltacloud/models/key.rb
248
249
  - lib/deltacloud/state_machine.rb
249
250
  - lib/deltacloud/validation.rb
250
251
  - lib/drivers.rb
@@ -313,6 +314,11 @@ files:
313
314
  - views/storage_volumes/index.xml.haml
314
315
  - views/storage_volumes/show.html.haml
315
316
  - views/storage_volumes/show.xml.haml
317
+ - views/keys/index.html.haml
318
+ - views/keys/index.xml.haml
319
+ - views/keys/new.html.haml
320
+ - views/keys/show.html.haml
321
+ - views/keys/show.xml.haml
316
322
  - views/instance_states/show.gv.erb
317
323
  - public/favicon.ico
318
324
  - public/images/grid.png