deltacloud-core 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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