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 +1 -1
- data/deltacloud.rb +1 -0
- data/lib/deltacloud/base_driver/base_driver.rb +29 -0
- data/lib/deltacloud/base_driver/features.rb +7 -0
- data/lib/deltacloud/base_driver/mock_driver.rb +4 -1
- data/lib/deltacloud/drivers/ec2/ec2_driver.rb +98 -31
- data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +25 -25
- data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +44 -22
- data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +47 -27
- data/lib/deltacloud/drivers/terremark/terremark_driver.rb +52 -28
- data/lib/deltacloud/helpers/application_helper.rb +6 -0
- data/lib/deltacloud/models/key.rb +35 -0
- data/lib/sinatra/url_for.rb +4 -1
- data/server.rb +53 -1
- data/views/errors/backend_error.html.haml +3 -1
- data/views/images/index.html.haml +1 -1
- data/views/instances/index.html.haml +1 -1
- data/views/instances/show.xml.haml +31 -22
- data/views/keys/index.html.haml +26 -0
- data/views/keys/index.xml.haml +4 -0
- data/views/keys/new.html.haml +8 -0
- data/views/keys/show.html.haml +22 -0
- data/views/keys/show.xml.haml +20 -0
- metadata +9 -3
data/config.ru
CHANGED
data/deltacloud.rb
CHANGED
@@ -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
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
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
|
-
|
191
|
-
|
192
|
-
|
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
|
-
|
198
|
-
|
199
|
-
|
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
|
-
|
205
|
-
|
206
|
-
|
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
|
-
|
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
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
101
|
-
|
102
|
-
|
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
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
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
|
-
|
82
|
-
|
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
|
-
|
87
|
-
|
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
|
-
|
96
|
-
|
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
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
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
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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
|
-
|
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
|
-
|
143
|
-
|
144
|
-
|
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
|
-
|
152
|
-
|
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
|
-
|
250
|
-
|
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
|
|
@@ -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
|
data/lib/sinatra/url_for.rb
CHANGED
@@ -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
|
-
|
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
|
@@ -1,30 +1,39 @@
|
|
1
1
|
!!! XML
|
2
2
|
%instance{:href => instance_url(@instance.id), :id => @instance.id}
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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 »', "#{url_for('/api/keys/new')}", :class => 'button'
|
@@ -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
|
-
-
|
9
|
-
version: 0.0.
|
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-
|
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
|