deltacloud-core 0.0.1 → 0.0.2
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/Rakefile +1 -24
- data/lib/deltacloud/base_driver/features.rb +15 -0
- data/lib/deltacloud/base_driver/mock_driver.rb +37 -0
- data/lib/deltacloud/drivers/ec2/ec2_driver.rb +70 -48
- data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +97 -14
- data/lib/deltacloud/drivers/{rimu/rimu_hosting_client.rb → rimuhosting/rimuhosting_client.rb} +5 -8
- data/lib/deltacloud/drivers/{rimu/rimu_hosting_driver.rb → rimuhosting/rimuhosting_driver.rb} +6 -5
- data/lib/deltacloud/drivers/terremark/terremark_driver.rb +261 -0
- data/lib/deltacloud/hardware_profile.rb +22 -0
- data/lib/deltacloud/helpers/application_helper.rb +18 -0
- data/lib/deltacloud/helpers/conversion_helper.rb +2 -3
- data/lib/deltacloud/method_serializer.rb +84 -0
- data/lib/drivers.rb +4 -3
- data/lib/sinatra/accept_media_types.rb +128 -0
- data/lib/sinatra/respond_to.rb +23 -16
- data/public/javascripts/application.js +30 -0
- data/public/javascripts/jquery-1.4.2.min.js +154 -0
- data/server.rb +23 -21
- data/support/fedora/deltacloudd +68 -0
- data/support/fedora/rubygem-deltacloud-core.spec +91 -0
- data/views/instances/index.html.haml +2 -1
- data/views/instances/index.xml.haml +3 -3
- data/views/instances/new.html.haml +9 -3
- data/views/instances/show.html.haml +2 -1
- data/views/instances/show.xml.haml +16 -3
- data/views/layout.html.haml +2 -0
- metadata +19 -37
- data/lib/converters/xml_converter.rb +0 -133
- data/public/javascripts/controls.js +0 -963
- data/public/javascripts/dragdrop.js +0 -973
- data/public/javascripts/effects.js +0 -1128
- data/public/javascripts/prototype.js +0 -4320
data/Rakefile
CHANGED
@@ -22,8 +22,6 @@ require 'rake'
|
|
22
22
|
require 'rake/testtask'
|
23
23
|
require 'rake/gempackagetask'
|
24
24
|
|
25
|
-
|
26
|
-
|
27
25
|
desc "Run basic unit tests"
|
28
26
|
Rake::TestTask.new("test") { |t|
|
29
27
|
t.test_files = FileList[
|
@@ -37,29 +35,8 @@ Rake::TestTask.new("test") { |t|
|
|
37
35
|
t.warning = false
|
38
36
|
}
|
39
37
|
|
40
|
-
begin
|
41
|
-
require 'cucumber'
|
42
|
-
require 'cucumber/rake/task'
|
43
|
-
|
44
|
-
Cucumber::Rake::Task.new(:features) do |t|
|
45
|
-
t.cucumber_opts = "features --format html --out tmp/cucumber.html"
|
46
|
-
t.rcov = false
|
47
|
-
end
|
48
|
-
|
49
|
-
Cucumber::Rake::Task.new(:rcov) do |t|
|
50
|
-
t.cucumber_opts = "features --format pretty"
|
51
|
-
t.rcov = true
|
52
|
-
t.rcov_opts << %[-o "tmp/coverage"]
|
53
|
-
end
|
54
|
-
rescue LoadError
|
55
|
-
desc 'Cucumber rake task not available'
|
56
|
-
task :features do
|
57
|
-
abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem'
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
|
62
38
|
load 'deltacloud-core.gemspec'
|
39
|
+
|
63
40
|
Rake::GemPackageTask.new(@spec) do |pkg|
|
64
41
|
pkg.need_tar = true
|
65
42
|
end
|
@@ -136,6 +136,21 @@ module Deltacloud
|
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
139
|
+
declare_feature :instances, :authentication_key do
|
140
|
+
operation :create do
|
141
|
+
param :keyname, :string, :optional, nil
|
142
|
+
"EC2 key authentification method"
|
143
|
+
end
|
144
|
+
operation :show do
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
declare_feature :instances, :authentication_password do
|
149
|
+
operation :create do
|
150
|
+
param :password, :string, :optional
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
139
154
|
declare_feature :instances, :hardware_profiles do
|
140
155
|
description "Size instances according to changes to a hardware profile"
|
141
156
|
# The parameters are filled in from the hardware profiles
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'deltacloud/method_serializer'
|
2
|
+
|
3
|
+
# Create 'mock' version of original driver client/gem:
|
4
|
+
|
5
|
+
module Mock
|
6
|
+
class EC2 < AWS::EC2::Base
|
7
|
+
|
8
|
+
include MethodSerializer::Cache
|
9
|
+
|
10
|
+
def self.cached_methods
|
11
|
+
[
|
12
|
+
:describe_images,
|
13
|
+
:describe_availability_zones,
|
14
|
+
:run_instances,
|
15
|
+
:describe_instances,
|
16
|
+
:reboot_instances,
|
17
|
+
:terminate_instances
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
MethodSerializer::Cache::wrap_methods(self, :cache_dir => File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'tests', 'ec2', 'support'))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# Replace original client with mock client
|
27
|
+
Deltacloud::Drivers::EC2::EC2Driver.class_eval do
|
28
|
+
alias_method :original_new_client, :new_client
|
29
|
+
|
30
|
+
def new_client(credentials, opts={})
|
31
|
+
Mock::EC2.new(
|
32
|
+
:access_key_id => credentials.user,
|
33
|
+
:secret_access_key => credentials.password
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -17,11 +17,16 @@
|
|
17
17
|
|
18
18
|
|
19
19
|
require 'deltacloud/base_driver'
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
require 'AWS'
|
21
|
+
|
22
|
+
class Instance
|
23
|
+
attr_accessor :keyname
|
24
|
+
attr_accessor :authn_error
|
25
|
+
|
26
|
+
def authn_feature_failed?
|
27
|
+
return true unless authn_error.nil?
|
28
|
+
end
|
29
|
+
|
25
30
|
end
|
26
31
|
|
27
32
|
module Deltacloud
|
@@ -30,54 +35,62 @@ module Deltacloud
|
|
30
35
|
class EC2Driver < Deltacloud::BaseDriver
|
31
36
|
|
32
37
|
feature :instances, :user_data
|
38
|
+
feature :instances, :authentication_key
|
33
39
|
|
34
|
-
define_hardware_profile('m1
|
35
|
-
cpu
|
36
|
-
memory
|
37
|
-
storage
|
38
|
-
architecture
|
40
|
+
define_hardware_profile('m1.small') do
|
41
|
+
cpu 1
|
42
|
+
memory 1.7 * 1024
|
43
|
+
storage 160
|
44
|
+
architecture 'i386'
|
39
45
|
end
|
40
46
|
|
41
|
-
define_hardware_profile('m1
|
47
|
+
define_hardware_profile('m1.large') do
|
42
48
|
cpu 4
|
43
|
-
memory
|
44
|
-
storage
|
45
|
-
architecture
|
49
|
+
memory 7.5 * 1024
|
50
|
+
storage 850
|
51
|
+
architecture 'x86_64'
|
46
52
|
end
|
47
53
|
|
48
|
-
define_hardware_profile('m1
|
54
|
+
define_hardware_profile('m1.xlarge') do
|
49
55
|
cpu 8
|
50
|
-
memory
|
51
|
-
storage
|
52
|
-
architecture
|
56
|
+
memory 15 * 1024
|
57
|
+
storage 1690
|
58
|
+
architecture 'x86_64'
|
53
59
|
end
|
54
60
|
|
55
|
-
define_hardware_profile('c1
|
61
|
+
define_hardware_profile('c1.medium') do
|
56
62
|
cpu 5
|
57
|
-
memory
|
58
|
-
storage
|
59
|
-
architecture
|
63
|
+
memory 1.7 * 1024
|
64
|
+
storage 350
|
65
|
+
architecture 'i386'
|
60
66
|
end
|
61
67
|
|
62
|
-
define_hardware_profile('c1
|
63
|
-
cpu
|
64
|
-
memory
|
65
|
-
storage
|
66
|
-
architecture
|
68
|
+
define_hardware_profile('c1.xlarge') do
|
69
|
+
cpu 20
|
70
|
+
memory 7 * 1024
|
71
|
+
storage 1690
|
72
|
+
architecture 'x86_64'
|
67
73
|
end
|
68
74
|
|
69
|
-
define_hardware_profile('m2
|
70
|
-
cpu
|
71
|
-
memory
|
72
|
-
storage
|
73
|
-
architecture
|
75
|
+
define_hardware_profile('m2.xlarge') do
|
76
|
+
cpu 6.5
|
77
|
+
memory 17.1 * 1024
|
78
|
+
storage 420
|
79
|
+
architecture 'x86_64'
|
74
80
|
end
|
75
81
|
|
76
|
-
define_hardware_profile('m2
|
77
|
-
cpu
|
78
|
-
memory
|
79
|
-
storage
|
80
|
-
architecture
|
82
|
+
define_hardware_profile('m2.2xlarge') do
|
83
|
+
cpu 13
|
84
|
+
memory 34.2 * 1024
|
85
|
+
storage 850
|
86
|
+
architecture 'x86_64'
|
87
|
+
end
|
88
|
+
|
89
|
+
define_hardware_profile('m2.4xlarge') do
|
90
|
+
cpu 26
|
91
|
+
memory 68.4 * 1024
|
92
|
+
storage 1690
|
93
|
+
architecture 'x86_64'
|
81
94
|
end
|
82
95
|
|
83
96
|
define_instance_states do
|
@@ -99,9 +112,14 @@ class EC2Driver < Deltacloud::BaseDriver
|
|
99
112
|
def images(credentials, opts={} )
|
100
113
|
ec2 = new_client(credentials)
|
101
114
|
img_arr = []
|
102
|
-
|
103
|
-
|
104
|
-
|
115
|
+
# if we know the image_id, we don't want to limit by owner_id, since this
|
116
|
+
# will exclude public images
|
117
|
+
if (opts and opts[:id])
|
118
|
+
config = { :image_id => opts[:id] }
|
119
|
+
else
|
120
|
+
config = { :owner_id => "amazon" }
|
121
|
+
config.merge!({ :owner_id => opts[:owner_id] }) if opts and opts[:owner_id]
|
122
|
+
end
|
105
123
|
safely do
|
106
124
|
ec2.describe_images(config).imagesSet.item.each do |image|
|
107
125
|
img_arr << convert_image(image)
|
@@ -156,10 +174,10 @@ class EC2Driver < Deltacloud::BaseDriver
|
|
156
174
|
ec2_instances = ec2.run_instances(
|
157
175
|
:image_id => image.id,
|
158
176
|
:user_data => opts[:user_data],
|
159
|
-
:key_name => opts[:
|
177
|
+
:key_name => opts[:keyname],
|
160
178
|
:availability_zone => realm_id,
|
161
179
|
:monitoring_enabled => true,
|
162
|
-
:instance_type => hwp.name
|
180
|
+
:instance_type => hwp.name,
|
163
181
|
:disable_api_termination => false,
|
164
182
|
:instance_initiated_shutdown_behavior => 'terminate'
|
165
183
|
)
|
@@ -235,10 +253,12 @@ class EC2Driver < Deltacloud::BaseDriver
|
|
235
253
|
private
|
236
254
|
|
237
255
|
def new_client(credentials)
|
238
|
-
|
256
|
+
opts = {
|
239
257
|
:access_key_id => credentials.user,
|
240
258
|
:secret_access_key => credentials.password
|
241
|
-
|
259
|
+
}
|
260
|
+
opts[:server] = ENV['DCLOUD_EC2_URL'] if ENV['DCLOUD_EC2_URL']
|
261
|
+
AWS::EC2::Base.new(opts)
|
242
262
|
end
|
243
263
|
|
244
264
|
def convert_image(ec2_image)
|
@@ -265,8 +285,8 @@ class EC2Driver < Deltacloud::BaseDriver
|
|
265
285
|
state_key = state.downcase.underscore.to_sym
|
266
286
|
realm_id = ec2_instance['placement']['availabilityZone']
|
267
287
|
(realm_id = nil ) if ( realm_id == '' )
|
268
|
-
hwp_name = ec2_instance['instanceType']
|
269
|
-
Instance.new( {
|
288
|
+
hwp_name = ec2_instance['instanceType']
|
289
|
+
instance = Instance.new( {
|
270
290
|
:id=>ec2_instance['instanceId'],
|
271
291
|
:name => ec2_instance['imageId'],
|
272
292
|
:state=>state,
|
@@ -275,10 +295,12 @@ class EC2Driver < Deltacloud::BaseDriver
|
|
275
295
|
:realm_id=>realm_id,
|
276
296
|
:public_addresses=>( ec2_instance['dnsName'] == '' ? [] : [ec2_instance['dnsName']] ),
|
277
297
|
:private_addresses=>( ec2_instance['privateDnsName'] == '' ? [] : [ec2_instance['privateDnsName']] ),
|
278
|
-
:flavor_id=>ec2_instance['instanceType'].gsub( /\./, '-'),
|
279
298
|
:instance_profile =>InstanceProfile.new(hwp_name),
|
280
299
|
:actions=>instance_actions_for( state ),
|
300
|
+
:keyname => ec2_instance['keyName']
|
281
301
|
} )
|
302
|
+
instance.authn_error = "Key not set for instance" unless ec2_instance['keyName']
|
303
|
+
return instance
|
282
304
|
end
|
283
305
|
|
284
306
|
def convert_volume(ec2_volume)
|
@@ -307,7 +329,7 @@ class EC2Driver < Deltacloud::BaseDriver
|
|
307
329
|
rescue AWS::AuthFailure => e
|
308
330
|
raise Deltacloud::AuthException.new
|
309
331
|
rescue Exception => e
|
310
|
-
puts "ERROR: #{e.message}"
|
332
|
+
puts "ERROR: #{e.message}\n#{e.backtrace.join("\n")}"
|
311
333
|
end
|
312
334
|
end
|
313
335
|
|
@@ -18,12 +18,24 @@
|
|
18
18
|
require 'deltacloud/base_driver'
|
19
19
|
require 'deltacloud/drivers/gogrid/gogrid_client'
|
20
20
|
|
21
|
+
class Instance
|
22
|
+
attr_accessor :username
|
23
|
+
attr_accessor :password
|
24
|
+
attr_accessor :authn_error
|
25
|
+
|
26
|
+
def authn_feature_failed?
|
27
|
+
return true unless authn_error.nil?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
21
31
|
module Deltacloud
|
22
32
|
module Drivers
|
23
33
|
module Gogrid
|
24
34
|
|
25
35
|
class GogridDriver < Deltacloud::BaseDriver
|
26
36
|
|
37
|
+
feature :instances, :authentication_password
|
38
|
+
|
27
39
|
define_hardware_profile 'server' do
|
28
40
|
cpu 2
|
29
41
|
memory [512, 1024, 2048, 4096, 8192]
|
@@ -76,30 +88,72 @@ class GogridDriver < Deltacloud::BaseDriver
|
|
76
88
|
else
|
77
89
|
server_ram = "512MB"
|
78
90
|
end
|
91
|
+
client = new_client(credentials)
|
79
92
|
name = (opts[:name] && opts[:name]!='') ? opts[:name] : get_random_instance_name
|
80
93
|
safely do
|
81
|
-
|
94
|
+
instance = client.request('grid/server/add', {
|
82
95
|
'name' => name,
|
83
96
|
'image' => image_id,
|
84
97
|
'server.ram' => server_ram,
|
85
98
|
'ip' => get_next_free_ip(credentials)
|
86
|
-
})['list'].first
|
99
|
+
})['list'].first
|
100
|
+
if instance
|
101
|
+
login_data = get_login_data(client, instance[:id])
|
102
|
+
if login_data['username'] and login_data['password']
|
103
|
+
instance['username'] = login_data['username']
|
104
|
+
instance['password'] = login_data['password']
|
105
|
+
inst = convert_instance(instance, credentials.user)
|
106
|
+
else
|
107
|
+
inst = convert_instance(instance, credentials.user)
|
108
|
+
inst.authn_error = "Unable to fetch password"
|
109
|
+
end
|
110
|
+
return inst
|
111
|
+
else
|
112
|
+
return nil
|
113
|
+
end
|
87
114
|
end
|
88
115
|
end
|
89
116
|
|
117
|
+
def list_instances(credentials, id)
|
118
|
+
instances = []
|
119
|
+
safely do
|
120
|
+
new_client(credentials).request('grid/server/list')['list'].collect do |instance|
|
121
|
+
if id.nil? or instance['name'] == id
|
122
|
+
instances << convert_instance(instance, credentials.user)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
instances
|
127
|
+
end
|
128
|
+
|
90
129
|
def instances(credentials, opts=nil)
|
91
130
|
instances = []
|
92
131
|
if opts and opts[:id]
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
convert_instance(instance, credentials.user)
|
132
|
+
begin
|
133
|
+
client = new_client(credentials)
|
134
|
+
instance = client.request('grid/server/get', { 'name' => opts[:id] })['list'].first
|
135
|
+
login_data = get_login_data(client, instance['id'])
|
136
|
+
if login_data['username'] and login_data['password']
|
137
|
+
instance['username'] = login_data['username']
|
138
|
+
instance['password'] = login_data['password']
|
139
|
+
inst = convert_instance(instance, credentials.user)
|
140
|
+
else
|
141
|
+
inst = convert_instance(instance, credentials.user)
|
142
|
+
inst.authn_error = "Unable to fetch password"
|
143
|
+
end
|
144
|
+
instances = [inst]
|
145
|
+
rescue Exception => e
|
146
|
+
if e.message == "400 Bad Request"
|
147
|
+
# in the case of a VM that we just made, the grid/server/get method
|
148
|
+
# throws a "400 Bad Request error". In this case we try again by
|
149
|
+
# getting a full listing a filtering on the id. This could
|
150
|
+
# potentially take a long time, but I don't see another way to get
|
151
|
+
# information about a newly created instance
|
152
|
+
instances = list_instances(credentials, opts[:id])
|
101
153
|
end
|
102
154
|
end
|
155
|
+
else
|
156
|
+
instances = list_instances(credentials, nil)
|
103
157
|
end
|
104
158
|
instances = filter_on( instances, :state, opts )
|
105
159
|
instances
|
@@ -111,15 +165,21 @@ class GogridDriver < Deltacloud::BaseDriver
|
|
111
165
|
end
|
112
166
|
end
|
113
167
|
|
168
|
+
def destroy_instance(credentials, id)
|
169
|
+
safely do
|
170
|
+
new_client(credentials).request('grid/server/delete', { 'id' => id})
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
114
174
|
def stop_instance(credentials, id)
|
115
175
|
safely do
|
116
176
|
new_client(credentials).request('grid/server/power', { 'id' => id, 'power' => 'off'})
|
117
177
|
end
|
118
178
|
end
|
119
179
|
|
120
|
-
def
|
180
|
+
def start_instance(credentials, id)
|
121
181
|
safely do
|
122
|
-
new_client(credentials).request('grid/server/
|
182
|
+
new_client(credentials).request('grid/server/power', { 'id' => id, 'power' => 'on'})
|
123
183
|
end
|
124
184
|
end
|
125
185
|
|
@@ -128,7 +188,8 @@ class GogridDriver < Deltacloud::BaseDriver
|
|
128
188
|
pending.to( :running ) .automatically
|
129
189
|
running.to( :stopped ) .on( :stop )
|
130
190
|
stopped.to( :running ) .on( :start )
|
131
|
-
|
191
|
+
running.to( :finish ) .on( :destroy )
|
192
|
+
stopped.to( :finish ) .on( :destroy )
|
132
193
|
end
|
133
194
|
|
134
195
|
private
|
@@ -137,6 +198,22 @@ class GogridDriver < Deltacloud::BaseDriver
|
|
137
198
|
GoGridClient.new('https://api.gogrid.com/api', credentials.user, credentials.password)
|
138
199
|
end
|
139
200
|
|
201
|
+
def get_login_data(client, instance_id)
|
202
|
+
login_data = {}
|
203
|
+
begin
|
204
|
+
client.request('support/password/list')['list'].each do |passwd|
|
205
|
+
next unless passwd['server']
|
206
|
+
if passwd['server']['id'] == instance_id
|
207
|
+
login_data['username'], login_data['password'] = passwd['username'], passwd['password']
|
208
|
+
break
|
209
|
+
end
|
210
|
+
end
|
211
|
+
rescue Exception => e
|
212
|
+
login_data[:error] = e.message
|
213
|
+
end
|
214
|
+
return login_data
|
215
|
+
end
|
216
|
+
|
140
217
|
def convert_image(gg_image, owner_id=nil)
|
141
218
|
Image.new( {
|
142
219
|
:id=>gg_image['id'],
|
@@ -190,6 +267,10 @@ class GogridDriver < Deltacloud::BaseDriver
|
|
190
267
|
prof = InstanceProfile.new("server", opts)
|
191
268
|
|
192
269
|
Instance.new(
|
270
|
+
# note that we use 'name' as the id here, because newly created instances
|
271
|
+
# don't get a real ID until later on. The name is good enough; from
|
272
|
+
# what I can tell, 'name' per user is unique, so it should be sufficient
|
273
|
+
# to uniquely identify this instance.
|
193
274
|
:id => instance['name'],
|
194
275
|
:owner_id => owner_id,
|
195
276
|
:image_id => instance['image']['id'],
|
@@ -200,7 +281,9 @@ class GogridDriver < Deltacloud::BaseDriver
|
|
200
281
|
:state => convert_server_state(instance['state']['name'], instance['id']),
|
201
282
|
:actions => instance_actions_for(convert_server_state(instance['state']['name'], instance['id'])),
|
202
283
|
:public_addresses => [ instance['ip']['ip'] ],
|
203
|
-
:private_addresses => []
|
284
|
+
:private_addresses => [],
|
285
|
+
:username => instance['username'],
|
286
|
+
:password => instance['password']
|
204
287
|
)
|
205
288
|
end
|
206
289
|
|