steamcannon-deltacloud-core 0.0.7.1-java
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +176 -0
- data/Rakefile +106 -0
- data/bin/deltacloudd +120 -0
- data/config.ru +5 -0
- data/deltacloud.rb +20 -0
- data/lib/deltacloud/base_driver/base_driver.rb +259 -0
- data/lib/deltacloud/base_driver/features.rb +173 -0
- data/lib/deltacloud/base_driver/mock_driver.rb +58 -0
- data/lib/deltacloud/base_driver.rb +20 -0
- data/lib/deltacloud/drivers/azure/azure_driver.rb +127 -0
- data/lib/deltacloud/drivers/ec2/ec2_driver.rb +580 -0
- data/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb +170 -0
- data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +50 -0
- data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +343 -0
- data/lib/deltacloud/drivers/gogrid/test.rb +13 -0
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob1.yml +5 -0
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob2.yml +5 -0
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob3.yml +5 -0
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob4.yml +5 -0
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob5.yml +5 -0
- data/lib/deltacloud/drivers/mock/data/buckets/bucket1.yml +2 -0
- data/lib/deltacloud/drivers/mock/data/buckets/bucket2.yml +2 -0
- data/lib/deltacloud/drivers/mock/data/images/img1.yml +3 -0
- data/lib/deltacloud/drivers/mock/data/images/img2.yml +3 -0
- data/lib/deltacloud/drivers/mock/data/images/img3.yml +3 -0
- data/lib/deltacloud/drivers/mock/data/instances/inst0.yml +16 -0
- data/lib/deltacloud/drivers/mock/data/instances/inst1.yml +9 -0
- data/lib/deltacloud/drivers/mock/data/instances/inst2.yml +9 -0
- data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap1.yml +4 -0
- data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap2.yml +4 -0
- data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap3.yml +4 -0
- data/lib/deltacloud/drivers/mock/data/storage_volumes/vol1.yml +6 -0
- data/lib/deltacloud/drivers/mock/data/storage_volumes/vol2.yml +6 -0
- data/lib/deltacloud/drivers/mock/data/storage_volumes/vol3.yml +6 -0
- data/lib/deltacloud/drivers/mock/mock_driver.rb +356 -0
- data/lib/deltacloud/drivers/opennebula/cloud_client.rb +116 -0
- data/lib/deltacloud/drivers/opennebula/occi_client.rb +204 -0
- data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +241 -0
- data/lib/deltacloud/drivers/rackspace/rackspace_client.rb +130 -0
- data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +290 -0
- data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +258 -0
- data/lib/deltacloud/drivers/rimuhosting/rimuhosting_client.rb +85 -0
- data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +166 -0
- data/lib/deltacloud/drivers/terremark/terremark_driver.rb +295 -0
- data/lib/deltacloud/hardware_profile.rb +153 -0
- data/lib/deltacloud/helpers/application_helper.rb +122 -0
- data/lib/deltacloud/helpers/blob_stream.rb +51 -0
- data/lib/deltacloud/helpers/conversion_helper.rb +39 -0
- data/lib/deltacloud/helpers/hardware_profiles_helper.rb +35 -0
- data/lib/deltacloud/helpers.rb +5 -0
- data/lib/deltacloud/method_serializer.rb +85 -0
- data/lib/deltacloud/models/base_model.rb +59 -0
- data/lib/deltacloud/models/blob.rb +26 -0
- data/lib/deltacloud/models/bucket.rb +24 -0
- data/lib/deltacloud/models/image.rb +27 -0
- data/lib/deltacloud/models/instance.rb +38 -0
- data/lib/deltacloud/models/instance_profile.rb +48 -0
- data/lib/deltacloud/models/key.rb +35 -0
- data/lib/deltacloud/models/realm.rb +26 -0
- data/lib/deltacloud/models/storage_snapshot.rb +27 -0
- data/lib/deltacloud/models/storage_volume.rb +28 -0
- data/lib/deltacloud/state_machine.rb +84 -0
- data/lib/deltacloud/validation.rb +70 -0
- data/lib/drivers.rb +51 -0
- data/lib/sinatra/accept_media_types.rb +128 -0
- data/lib/sinatra/lazy_auth.rb +56 -0
- data/lib/sinatra/rabbit.rb +279 -0
- data/lib/sinatra/respond_to.rb +238 -0
- data/lib/sinatra/static_assets.rb +83 -0
- data/lib/sinatra/url_for.rb +53 -0
- data/public/favicon.ico +0 -0
- data/public/images/grid.png +0 -0
- data/public/images/logo-wide.png +0 -0
- data/public/images/rails.png +0 -0
- data/public/images/topbar-bg.png +0 -0
- data/public/javascripts/application.js +32 -0
- data/public/javascripts/jquery-1.4.2.min.js +154 -0
- data/public/stylesheets/compiled/application.css +613 -0
- data/public/stylesheets/compiled/ie.css +31 -0
- data/public/stylesheets/compiled/print.css +27 -0
- data/public/stylesheets/compiled/screen.css +456 -0
- data/server.rb +516 -0
- data/support/fedora/deltacloudd +68 -0
- data/support/fedora/rubygem-deltacloud-core.spec +91 -0
- data/tests/api_test.rb +37 -0
- data/tests/hardware_profiles_test.rb +120 -0
- data/tests/images_test.rb +111 -0
- data/tests/instance_states_test.rb +51 -0
- data/tests/instances_test.rb +222 -0
- data/tests/realms_test.rb +78 -0
- data/tests/url_for_test.rb +50 -0
- data/views/accounts/index.html.haml +11 -0
- data/views/accounts/show.html.haml +30 -0
- data/views/api/show.html.haml +15 -0
- data/views/api/show.xml.haml +5 -0
- data/views/blobs/show.html.haml +20 -0
- data/views/blobs/show.xml.haml +7 -0
- data/views/buckets/index.html.haml +33 -0
- data/views/buckets/index.xml.haml +10 -0
- data/views/buckets/new.html.haml +13 -0
- data/views/buckets/show.html.haml +19 -0
- data/views/buckets/show.xml.haml +8 -0
- data/views/docs/collection.html.haml +37 -0
- data/views/docs/collection.xml.haml +14 -0
- data/views/docs/index.html.haml +15 -0
- data/views/docs/index.xml.haml +5 -0
- data/views/docs/operation.html.haml +31 -0
- data/views/docs/operation.xml.haml +10 -0
- data/views/errors/auth_exception.html.haml +8 -0
- data/views/errors/auth_exception.xml.haml +2 -0
- data/views/errors/backend_error.html.haml +19 -0
- data/views/errors/backend_error.xml.haml +8 -0
- data/views/errors/not_found.html.haml +6 -0
- data/views/errors/not_found.xml.haml +2 -0
- data/views/errors/validation_failure.html.haml +11 -0
- data/views/errors/validation_failure.xml.haml +7 -0
- data/views/hardware_profiles/index.html.haml +25 -0
- data/views/hardware_profiles/index.xml.haml +4 -0
- data/views/hardware_profiles/show.html.haml +19 -0
- data/views/hardware_profiles/show.xml.haml +18 -0
- data/views/images/index.html.haml +30 -0
- data/views/images/index.xml.haml +8 -0
- data/views/images/show.html.haml +21 -0
- data/views/images/show.xml.haml +5 -0
- data/views/instance_states/show.html.haml +31 -0
- data/views/instance_states/show.png.erb +45 -0
- data/views/instance_states/show.xml.haml +8 -0
- data/views/instances/index.html.haml +30 -0
- data/views/instances/index.xml.haml +21 -0
- data/views/instances/new.html.haml +55 -0
- data/views/instances/show.html.haml +43 -0
- data/views/instances/show.xml.haml +49 -0
- 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
- data/views/layout.html.haml +26 -0
- data/views/realms/index.html.haml +29 -0
- data/views/realms/index.xml.haml +10 -0
- data/views/realms/show.html.haml +15 -0
- data/views/realms/show.xml.haml +9 -0
- data/views/root/index.html.haml +4 -0
- data/views/storage_snapshots/index.html.haml +20 -0
- data/views/storage_snapshots/index.xml.haml +9 -0
- data/views/storage_snapshots/show.html.haml +14 -0
- data/views/storage_snapshots/show.xml.haml +7 -0
- data/views/storage_volumes/index.html.haml +21 -0
- data/views/storage_volumes/index.xml.haml +23 -0
- data/views/storage_volumes/show.html.haml +20 -0
- data/views/storage_volumes/show.xml.haml +24 -0
- metadata +367 -0
data/server.rb
ADDED
@@ -0,0 +1,516 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'deltacloud'
|
3
|
+
require 'drivers'
|
4
|
+
require 'json'
|
5
|
+
require 'sinatra/respond_to'
|
6
|
+
require 'sinatra/static_assets'
|
7
|
+
require 'sinatra/rabbit'
|
8
|
+
require 'sinatra/lazy_auth'
|
9
|
+
require 'erb'
|
10
|
+
require 'haml'
|
11
|
+
require 'open3'
|
12
|
+
require 'lib/deltacloud/helpers/blob_stream'
|
13
|
+
|
14
|
+
configure do
|
15
|
+
set :raise_errors => false
|
16
|
+
set :show_exceptions, false
|
17
|
+
end
|
18
|
+
|
19
|
+
configure :development do
|
20
|
+
# So we can just use puts for logging
|
21
|
+
$stdout.sync = true
|
22
|
+
$stderr.sync = true
|
23
|
+
end
|
24
|
+
|
25
|
+
# You could use $API_HOST environment variable to change your hostname to
|
26
|
+
# whatever you want (eg. if you running API behind NAT)
|
27
|
+
HOSTNAME=ENV['API_HOST'] ? ENV['API_HOST'] : nil
|
28
|
+
|
29
|
+
error Deltacloud::Validation::Failure do
|
30
|
+
report_error(400, "validation_failure")
|
31
|
+
end
|
32
|
+
|
33
|
+
error Deltacloud::AuthException do
|
34
|
+
report_error(403, "auth_exception")
|
35
|
+
end
|
36
|
+
|
37
|
+
error Deltacloud::BackendError do
|
38
|
+
report_error(500, "backend_error")
|
39
|
+
end
|
40
|
+
|
41
|
+
Sinatra::Application.register Sinatra::RespondTo
|
42
|
+
|
43
|
+
# Redirect to /api
|
44
|
+
get '/' do redirect url_for('/api'); end
|
45
|
+
|
46
|
+
get '/api\/?' do
|
47
|
+
@version = 0.1
|
48
|
+
if params[:force_auth]
|
49
|
+
return [401, 'Authentication failed'] unless driver.valid_credentials?(credentials)
|
50
|
+
end
|
51
|
+
respond_to do |format|
|
52
|
+
format.xml { haml :"api/show" }
|
53
|
+
format.json do
|
54
|
+
{ :api => {
|
55
|
+
:version => @version,
|
56
|
+
:driver => DRIVER,
|
57
|
+
:links => entry_points.collect { |l| { :rel => l[0], :href => l[1]} }
|
58
|
+
}
|
59
|
+
}.to_json
|
60
|
+
end
|
61
|
+
format.html { haml :"api/show" }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Rabbit DSL
|
66
|
+
|
67
|
+
collection :realms do
|
68
|
+
description <<END
|
69
|
+
Within a cloud provider a realm represents a boundary containing resources.
|
70
|
+
The exact definition of a realm is left to the cloud provider.
|
71
|
+
In some cases, a realm may represent different datacenters, different continents,
|
72
|
+
or different pools of resources within a single datacenter.
|
73
|
+
A cloud provider may insist that resources must all exist within a single realm in
|
74
|
+
order to cooperate. For instance, storage volumes may only be allowed to be mounted to
|
75
|
+
instances within the same realm.
|
76
|
+
END
|
77
|
+
|
78
|
+
operation :index do
|
79
|
+
description <<END
|
80
|
+
Operation will list all available realms. Realms can be filtered using
|
81
|
+
the "architecture" parameter.
|
82
|
+
END
|
83
|
+
param :id, :string
|
84
|
+
param :architecture, :string, :optional, [ 'i386', 'x86_64' ]
|
85
|
+
control { filter_all(:realms) }
|
86
|
+
end
|
87
|
+
|
88
|
+
#FIXME: It always shows whole list
|
89
|
+
operation :show do
|
90
|
+
description 'Show an realm identified by "id" parameter.'
|
91
|
+
param :id, :string, :required
|
92
|
+
control { show(:realm) }
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
collection :images do
|
98
|
+
description <<END
|
99
|
+
An image is a platonic form of a machine. Images are not directly executable,
|
100
|
+
but are a template for creating actual instances of machines."
|
101
|
+
END
|
102
|
+
|
103
|
+
operation :index do
|
104
|
+
description <<END
|
105
|
+
The images collection will return a set of all images
|
106
|
+
available to the current use. Images can be filtered using the
|
107
|
+
"owner_id" and "architecture" parameters.
|
108
|
+
END
|
109
|
+
param :id, :string
|
110
|
+
param :architecture, :string, :optional
|
111
|
+
control { filter_all(:images) }
|
112
|
+
end
|
113
|
+
|
114
|
+
operation :show do
|
115
|
+
description 'Show an image identified by "id" parameter.'
|
116
|
+
param :id, :string, :required
|
117
|
+
control { show(:image) }
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
collection :instance_states do
|
123
|
+
description "The possible states of an instance, and how to traverse between them "
|
124
|
+
|
125
|
+
operation :index do
|
126
|
+
control do
|
127
|
+
@machine = driver.instance_state_machine
|
128
|
+
respond_to do |format|
|
129
|
+
format.xml { haml :'instance_states/show', :layout => false }
|
130
|
+
format.json do
|
131
|
+
out = []
|
132
|
+
@machine.states.each do |state|
|
133
|
+
transitions = state.transitions.collect do |t|
|
134
|
+
t.automatically? ? {:to => t.destination, :auto => 'true'} : {:to => t.destination, :action => t.action}
|
135
|
+
end
|
136
|
+
out << { :name => state, :transitions => transitions }
|
137
|
+
end
|
138
|
+
out.to_json
|
139
|
+
end
|
140
|
+
format.html { haml :'instance_states/show'}
|
141
|
+
format.gv { erb :"instance_states/show" }
|
142
|
+
format.png do
|
143
|
+
# Trick respond_to into looking up the right template for the
|
144
|
+
# graphviz file
|
145
|
+
format_backup = format
|
146
|
+
format(:gv)
|
147
|
+
gv = erb(:"instance_states/show")
|
148
|
+
format(format_backup)
|
149
|
+
png = ''
|
150
|
+
cmd = 'dot -Kdot -Gpad="0.2,0.2" -Gsize="5.0,8.0" -Gdpi="180" -Tpng'
|
151
|
+
Open3.popen3( cmd ) do |stdin, stdout, stderr|
|
152
|
+
stdin.write( gv )
|
153
|
+
stdin.close()
|
154
|
+
png = stdout.read
|
155
|
+
end
|
156
|
+
content_type 'image/png'
|
157
|
+
png
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
get "/api/instances/new" do
|
165
|
+
@instance = Instance.new( { :id=>params[:id], :image_id=>params[:image_id] } )
|
166
|
+
@image = driver.image( credentials, :id => params[:image_id] )
|
167
|
+
@hardware_profiles = driver.hardware_profiles(credentials, :architecture => @image.architecture )
|
168
|
+
@realms = driver.realms(credentials)
|
169
|
+
respond_to do |format|
|
170
|
+
format.html { haml :"instances/new" }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
collection :instances do
|
175
|
+
description <<END
|
176
|
+
An instance is a concrete machine realized from an image.
|
177
|
+
The images collection may be obtained by following the link from the primary entry-point."
|
178
|
+
END
|
179
|
+
|
180
|
+
operation :index do
|
181
|
+
description "List all instances."
|
182
|
+
param :id, :string, :optional
|
183
|
+
param :state, :string, :optional
|
184
|
+
control { filter_all(:instances) }
|
185
|
+
end
|
186
|
+
|
187
|
+
operation :show do
|
188
|
+
description 'Show an instance identified by "id" parameter.'
|
189
|
+
param :id, :string, :required
|
190
|
+
control { show(:instance) }
|
191
|
+
end
|
192
|
+
|
193
|
+
operation :create do
|
194
|
+
description "Create a new instance."
|
195
|
+
param :image_id, :string, :required
|
196
|
+
param :realm_id, :string, :optional
|
197
|
+
param :hwp_id, :string, :optional
|
198
|
+
control do
|
199
|
+
@image = driver.image(credentials, :id => params[:image_id])
|
200
|
+
instance = driver.create_instance(credentials, @image.id, params)
|
201
|
+
respond_to do |format|
|
202
|
+
format.xml do
|
203
|
+
response.status = 201 # Created
|
204
|
+
response['Location'] = instance_url(instance.id)
|
205
|
+
@instance = instance
|
206
|
+
haml :"instances/show"
|
207
|
+
end
|
208
|
+
format.html do
|
209
|
+
redirect instance_url(instance.id) if instance and instance.id
|
210
|
+
redirect instances_url
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
operation :reboot, :method => :post, :member => true do
|
217
|
+
description "Reboot a running instance."
|
218
|
+
param :id, :string, :required
|
219
|
+
control { instance_action(:reboot) }
|
220
|
+
end
|
221
|
+
|
222
|
+
operation :start, :method => :post, :member => true do
|
223
|
+
description "Start an instance."
|
224
|
+
param :id, :string, :required
|
225
|
+
control { instance_action(:start) }
|
226
|
+
end
|
227
|
+
|
228
|
+
operation :stop, :method => :post, :member => true do
|
229
|
+
description "Stop a running instance."
|
230
|
+
param :id, :string, :required
|
231
|
+
control { instance_action(:stop) }
|
232
|
+
end
|
233
|
+
|
234
|
+
operation :destroy do
|
235
|
+
description "Destroy an instance."
|
236
|
+
param :id, :string, :required
|
237
|
+
control { instance_action(:destroy) }
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
collection :hardware_profiles do
|
242
|
+
description <<END
|
243
|
+
A hardware profile represents a configuration of resources upon which a
|
244
|
+
machine may be deployed. It defines aspects such as local disk storage,
|
245
|
+
available RAM, and architecture. Each provider is free to define as many
|
246
|
+
(or as few) hardware profiles as desired.
|
247
|
+
END
|
248
|
+
|
249
|
+
operation :index do
|
250
|
+
description "List of available hardware profiles."
|
251
|
+
param :id, :string
|
252
|
+
param :architecture, :string, :optional, [ 'i386', 'x86_64' ]
|
253
|
+
control do
|
254
|
+
@profiles = driver.hardware_profiles(credentials, params)
|
255
|
+
respond_to do |format|
|
256
|
+
format.xml { haml :'hardware_profiles/index' }
|
257
|
+
format.html { haml :'hardware_profiles/index' }
|
258
|
+
format.json { convert_to_json(:hardware_profile, @profiles) }
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
operation :show do
|
264
|
+
description "Show specific hardware profile."
|
265
|
+
param :id, :string, :required
|
266
|
+
control do
|
267
|
+
@profile = driver.hardware_profile(credentials, params[:id])
|
268
|
+
if @profile
|
269
|
+
respond_to do |format|
|
270
|
+
format.xml { haml :'hardware_profiles/show', :layout => false }
|
271
|
+
format.html { haml :'hardware_profiles/show' }
|
272
|
+
format.json { convert_to_json(:hardware_profile, @profile) }
|
273
|
+
end
|
274
|
+
else
|
275
|
+
report_error(404, 'not_found')
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|
281
|
+
|
282
|
+
collection :storage_snapshots do
|
283
|
+
description "Storage snapshots description here"
|
284
|
+
|
285
|
+
operation :index do
|
286
|
+
description "List of storage snapshots."
|
287
|
+
param :id, :string
|
288
|
+
control { filter_all(:storage_snapshots) }
|
289
|
+
end
|
290
|
+
|
291
|
+
operation :show do
|
292
|
+
description "Show storage snapshot."
|
293
|
+
param :id, :string, :required
|
294
|
+
control { show(:storage_snapshot) }
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
# get '/api/storage_volumes/new' do
|
299
|
+
# respond_to do |format|
|
300
|
+
# format.html { haml :"storage_volumes/new" }
|
301
|
+
# end
|
302
|
+
# end
|
303
|
+
|
304
|
+
collection :storage_volumes do
|
305
|
+
description "Storage volumes description here"
|
306
|
+
|
307
|
+
operation :index do
|
308
|
+
description "List of storage volumes."
|
309
|
+
param :id, :string
|
310
|
+
control { filter_all(:storage_volumes) }
|
311
|
+
end
|
312
|
+
|
313
|
+
operation :show do
|
314
|
+
description "Show storage volume."
|
315
|
+
param :id, :string, :required
|
316
|
+
control { show(:storage_volume) }
|
317
|
+
end
|
318
|
+
|
319
|
+
operation :create do
|
320
|
+
description "Create new storage volume if backend supports them."
|
321
|
+
param :realm_id, :string, :required
|
322
|
+
param :capacity, :string, :required
|
323
|
+
control(:with_feature => :create_storage_volume) do
|
324
|
+
volume = driver.create_storage_volume(credentials, params)
|
325
|
+
respond_to do |format|
|
326
|
+
format.xml do
|
327
|
+
response.status = 201 # Created
|
328
|
+
response['Location'] = storage_volume_url(volume.id)
|
329
|
+
@storage_volume = volume
|
330
|
+
haml :"storage_volumes/show"
|
331
|
+
end
|
332
|
+
format.html do
|
333
|
+
redirect storage_volume_url(volume.id) if volume and volume.id
|
334
|
+
redirect storage_volumes_url
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
operation :destroy do
|
341
|
+
param :id, :string, :required
|
342
|
+
control :with_feature => :destroy_storage_volume do
|
343
|
+
driver.destroy_storage_volume(credentials, params[:id])
|
344
|
+
redirect(storage_volumes_url)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
operation :attach, :method => :post, :member => true do
|
349
|
+
param :id, :string, :required
|
350
|
+
param :instance_id, :string, :required
|
351
|
+
param :device, :string, :required
|
352
|
+
|
353
|
+
control :with_feature => :attach_storage_volume do
|
354
|
+
volume = driver.attach_storage_volume(credentials, params)
|
355
|
+
respond_to do |format|
|
356
|
+
format.xml do
|
357
|
+
response.status = 200
|
358
|
+
response['Location'] = storage_volume_url(volume.id)
|
359
|
+
@storage_volume = volume
|
360
|
+
haml :"storage_volumes/show"
|
361
|
+
end
|
362
|
+
format.html do
|
363
|
+
redirect storage_volume_url(volume.id)
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
|
370
|
+
operation :detach, :method => :post, :member => true do
|
371
|
+
param :id, :string, :required
|
372
|
+
|
373
|
+
control :with_feature => :detach_storage_volume do
|
374
|
+
volume = driver.detach_storage_volume(credentials, params[:id])
|
375
|
+
respond_to do |format|
|
376
|
+
format.xml do
|
377
|
+
response.status = 200
|
378
|
+
response['Location'] = storage_volume_url(volume.id)
|
379
|
+
@storage_volume = volume
|
380
|
+
haml :"storage_volumes/show"
|
381
|
+
end
|
382
|
+
format.html do
|
383
|
+
redirect storage_volume_url(volume.id)
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
end
|
390
|
+
|
391
|
+
get '/api/keys/new' do
|
392
|
+
respond_to do |format|
|
393
|
+
format.html { haml :"keys/new" }
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
collection :keys do
|
398
|
+
description "Instance authentication credentials."
|
399
|
+
|
400
|
+
operation :index do
|
401
|
+
description "List all available credentials which could be used for instance authentication."
|
402
|
+
control do
|
403
|
+
filter_all :keys
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
operation :show do
|
408
|
+
description "Show details about given instance credential."
|
409
|
+
param :id, :string, :required
|
410
|
+
control { show :key }
|
411
|
+
end
|
412
|
+
|
413
|
+
operation :create do
|
414
|
+
description "Create a new instance credential if backend supports this."
|
415
|
+
param :name, :string, :required
|
416
|
+
control do
|
417
|
+
unless driver.respond_to?(:create_key)
|
418
|
+
raise Deltacloud::BackendFeatureUnsupported.new('501',
|
419
|
+
'Creating instance credentials is not supported in backend')
|
420
|
+
end
|
421
|
+
@key = driver.create_key(credentials, { :key_name => params[:name] })
|
422
|
+
respond_to do |format|
|
423
|
+
format.html { haml :"keys/show" }
|
424
|
+
format.xml { haml :"keys/show" }
|
425
|
+
end
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
operation :destroy do
|
430
|
+
description "Destroy given instance credential if backend supports this."
|
431
|
+
param :id, :string, :required
|
432
|
+
control do
|
433
|
+
unless driver.respond_to?(:destroy_key)
|
434
|
+
raise Deltacloud::BackendFeatureUnsupported.new('501',
|
435
|
+
'Creating instance credentials is not supported in backend')
|
436
|
+
end
|
437
|
+
driver.destroy_key(credentials, { :key_name => params[:id]})
|
438
|
+
redirect(keys_url)
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
end
|
443
|
+
|
444
|
+
get '/api/buckets/:bucket/:blob' do
|
445
|
+
@blob = driver.blob(credentials, { :id => params[:blob], 'bucket' => params[:bucket]})
|
446
|
+
if @blob
|
447
|
+
respond_to do |format|
|
448
|
+
format.html { haml :"blobs/show" }
|
449
|
+
format.xml { haml :"blobs/show" }
|
450
|
+
format.json { convert_to_json(blobs, @blob) }
|
451
|
+
end
|
452
|
+
else
|
453
|
+
report_error(404, 'not_found')
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
get '/api/buckets/new' do
|
458
|
+
respond_to do |format|
|
459
|
+
format.html { haml :"buckets/new" }
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
|
464
|
+
get '/api/buckets/:bucket/:blob/content' do
|
465
|
+
@blob = driver.blob(credentials, { :id => params[:blob], 'bucket' => params[:bucket]})
|
466
|
+
params['content_length'] = @blob.content_length
|
467
|
+
params['content_type'] = @blob.content_type
|
468
|
+
BlobStream.call(env, credentials, params)
|
469
|
+
end
|
470
|
+
|
471
|
+
collection :buckets do
|
472
|
+
description "Cloud Storage buckets - aka buckets|directories|folders"
|
473
|
+
|
474
|
+
operation :index do
|
475
|
+
description "List buckets associated with this account"
|
476
|
+
param :id, :string
|
477
|
+
param :name, :string
|
478
|
+
param :size, :string
|
479
|
+
control { filter_all(:buckets) }
|
480
|
+
end
|
481
|
+
|
482
|
+
operation :show do
|
483
|
+
description "Show bucket"
|
484
|
+
param :id, :string
|
485
|
+
control { show(:bucket) }
|
486
|
+
end
|
487
|
+
|
488
|
+
operation :create do
|
489
|
+
description "Create a new bucket (POST /api/buckets)"
|
490
|
+
param :name, :string, :required
|
491
|
+
control do
|
492
|
+
@bucket = driver.create_bucket(credentials, params[:name], params)
|
493
|
+
respond_to do |format|
|
494
|
+
format.xml do
|
495
|
+
response.status = 201 # Created
|
496
|
+
response['Location'] = bucket_url(@bucket.id)
|
497
|
+
haml :"buckets/show"
|
498
|
+
end
|
499
|
+
format.html do
|
500
|
+
redirect bucket_url(@bucket.id) if @bucket and @bucket.id
|
501
|
+
redirect buckets_url
|
502
|
+
end
|
503
|
+
end
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
operation :destroy do
|
508
|
+
description "Delete a bucket by name - bucket must be empty"
|
509
|
+
param :id, :string, :required
|
510
|
+
control do
|
511
|
+
driver.delete_bucket(credentials, params[:id], params)
|
512
|
+
redirect(buckets_url)
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'optparse'
|
5
|
+
require 'thin'
|
6
|
+
|
7
|
+
options = {
|
8
|
+
:env => 'production'
|
9
|
+
}
|
10
|
+
optparse = OptionParser.new do |opts|
|
11
|
+
|
12
|
+
opts.banner = <<BANNER
|
13
|
+
Usage:
|
14
|
+
deltacloudd -i <driver> [options]
|
15
|
+
|
16
|
+
Options:
|
17
|
+
BANNER
|
18
|
+
opts.on( '-i', '--driver DRIVER', 'Driver to use') do |driver|
|
19
|
+
ENV["API_DRIVER"] = driver
|
20
|
+
end
|
21
|
+
opts.on( '-r', '--hostname HOSTNAME',
|
22
|
+
'Bind to HOST address (default: localhost)') do |host|
|
23
|
+
ENV["API_HOST"] = host
|
24
|
+
end
|
25
|
+
opts.on( '-p', '--port PORT', 'Use PORT (default: 3001)') do |port|
|
26
|
+
ENV["API_PORT"] = port
|
27
|
+
end
|
28
|
+
opts.on( '-e', '--env ENV', 'Environment (default: "development")') { |env| options[:env] = env }
|
29
|
+
opts.on( '-h', '--help', '') { options[:help] = true }
|
30
|
+
end
|
31
|
+
|
32
|
+
optparse.parse!
|
33
|
+
|
34
|
+
if options[:help]
|
35
|
+
puts optparse
|
36
|
+
exit(0)
|
37
|
+
end
|
38
|
+
|
39
|
+
unless ENV["API_DRIVER"]
|
40
|
+
puts "You need to specify a driver to use (-i <driver>)"
|
41
|
+
exit(1)
|
42
|
+
end
|
43
|
+
|
44
|
+
ENV["API_HOST"] = "localhost" unless ENV["API_HOST"]
|
45
|
+
ENV["API_PORT"] = "3001" unless ENV["API_PORT"]
|
46
|
+
|
47
|
+
dirname="#{File.dirname(__FILE__)}/.."
|
48
|
+
|
49
|
+
argv_opts = ARGV.clone
|
50
|
+
argv_opts << ['start'] unless Thin::Runner.commands.include?(options[0])
|
51
|
+
argv_opts << ['--address', ENV["API_HOST"] ]
|
52
|
+
argv_opts << ['--port', ENV["API_PORT"] ]
|
53
|
+
argv_opts << ['--rackup', 'config.ru' ]
|
54
|
+
argv_opts << ['--chdir', dirname ]
|
55
|
+
argv_opts << ['-e', options[:env] ]
|
56
|
+
argv_opts << ['--threaded', '-D', '--stats', '/stats']
|
57
|
+
|
58
|
+
argv_opts.flatten!
|
59
|
+
|
60
|
+
puts "Starting Deltacloud API :: #{ENV["API_DRIVER"]} :: http://#{ENV["API_HOST"]}:#{ENV["API_PORT"]}/api"
|
61
|
+
puts
|
62
|
+
|
63
|
+
thin = Thin::Runner.new(argv_opts)
|
64
|
+
begin
|
65
|
+
thin.run!
|
66
|
+
rescue Exception => e
|
67
|
+
puts "ERROR: #{e.message}"
|
68
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
%global ruby_sitelib %(ruby -rrbconfig -e "puts Config::CONFIG['sitelibdir']")
|
2
|
+
%global gemdir %(ruby -rubygems -e 'puts Gem::dir' 2>/dev/null)
|
3
|
+
%global gemname deltacloud-core
|
4
|
+
%global geminstdir %{gemdir}/gems/%{gemname}-%{version}
|
5
|
+
|
6
|
+
Summary: Deltacloud REST API
|
7
|
+
Name: rubygem-%{gemname}
|
8
|
+
Version: 0.0.1
|
9
|
+
Release: 2%{?dist}
|
10
|
+
Group: Development/Languages
|
11
|
+
License: ASL 2.0 and MIT
|
12
|
+
URL: http://www.deltacloud.org
|
13
|
+
Source0: http://gems.rubyforge.org/gems/%{gemname}-%{version}.gem
|
14
|
+
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
15
|
+
Requires: rubygems
|
16
|
+
Requires: ruby(abi) = 1.8
|
17
|
+
Requires: rubygem(eventmachine) >= 0.12.10
|
18
|
+
Requires: rubygem(haml) >= 2.2.17
|
19
|
+
Requires: rubygem(sinatra) >= 0.9.4
|
20
|
+
Requires: rubygem(rack) >= 1.0.0
|
21
|
+
Requires: rubygem(thin) >= 1.2.5
|
22
|
+
Requires: rubygem(builder) >= 2.1.2
|
23
|
+
Requires: rubygem(json) >= 1.2.3
|
24
|
+
BuildRequires: ruby-json >= 1.1.9
|
25
|
+
BuildRequires: rubygem(rake) >= 0.8.7
|
26
|
+
BuildRequires: rubygem(rack-test) >= 0.4.0
|
27
|
+
BuildRequires: rubygem(cucumber) >= 0.4.0
|
28
|
+
BuildRequires: rubygem(rcov) >= 0.9.6
|
29
|
+
BuildRequires: rubygems
|
30
|
+
BuildRequires: ruby(abi) = 1.8
|
31
|
+
BuildArch: noarch
|
32
|
+
Provides: rubygem(%{gemname}) = %{version}
|
33
|
+
|
34
|
+
%description
|
35
|
+
The Deltacloud API is built as a service-based REST API.
|
36
|
+
You do not directly link a Deltacloud library into your program to use it.
|
37
|
+
Instead, a client speaks the Deltacloud API over HTTP to a server
|
38
|
+
which implements the REST interface.
|
39
|
+
|
40
|
+
%prep
|
41
|
+
|
42
|
+
%build
|
43
|
+
|
44
|
+
%install
|
45
|
+
rm -rf %{buildroot}
|
46
|
+
mkdir -p %{buildroot}%{gemdir}
|
47
|
+
gem install --local --install-dir %{buildroot}%{gemdir} \
|
48
|
+
--force --rdoc %{SOURCE0}
|
49
|
+
mkdir -p %{buildroot}/%{_bindir}
|
50
|
+
mv %{buildroot}%{geminstdir}/support/fedora/deltacloudd %{buildroot}/%{geminstdir}/bin
|
51
|
+
mv %{buildroot}%{gemdir}/bin/* %{buildroot}/%{_bindir}
|
52
|
+
rmdir %{buildroot}%{gemdir}/bin
|
53
|
+
find %{buildroot}%{geminstdir}/bin -type f | xargs chmod a+x
|
54
|
+
|
55
|
+
# Needs json_pure gem / not available in Fedora yet
|
56
|
+
#%check
|
57
|
+
#pushd %{buildroot}%{geminstdir}
|
58
|
+
#cucumber features/*.feature
|
59
|
+
#popd
|
60
|
+
|
61
|
+
%clean
|
62
|
+
rm -rf %{buildroot}
|
63
|
+
|
64
|
+
%files
|
65
|
+
%defattr(-, root, root, -)
|
66
|
+
%{_bindir}/deltacloudd
|
67
|
+
%{gemdir}/gems/%{gemname}-%{version}/bin
|
68
|
+
%{gemdir}/gems/%{gemname}-%{version}/lib
|
69
|
+
%{gemdir}/gems/%{gemname}-%{version}/public/favicon.ico
|
70
|
+
%{gemdir}/gems/%{gemname}-%{version}/public/images
|
71
|
+
%{gemdir}/gems/%{gemname}-%{version}/public/stylesheets
|
72
|
+
%{gemdir}/gems/%{gemname}-%{version}/tests
|
73
|
+
%{gemdir}/gems/%{gemname}-%{version}/views
|
74
|
+
%{gemdir}/gems/%{gemname}-%{version}/Rakefile
|
75
|
+
%{gemdir}/gems/%{gemname}-%{version}/*.rb
|
76
|
+
%{gemdir}/gems/%{gemname}-%{version}/config.ru
|
77
|
+
%doc %{gemdir}/gems/%{gemname}-%{version}/support/fedora
|
78
|
+
%doc %{gemdir}/gems/%{gemname}-%{version}/COPYING
|
79
|
+
%doc %{gemdir}/doc/%{gemname}-%{version}
|
80
|
+
%{gemdir}/cache/%{gemname}-%{version}.gem
|
81
|
+
%{gemdir}/specifications/%{gemname}-%{version}.gemspec
|
82
|
+
# MIT
|
83
|
+
%{gemdir}/gems/%{gemname}-%{version}/public/javascripts
|
84
|
+
|
85
|
+
%changelog
|
86
|
+
* Mon Apr 26 2010 Michal Fojtik <mfojtik@packager> - 0.0.1-1
|
87
|
+
- Initial package
|
88
|
+
|
89
|
+
* Mon Apr 26 2010 Michal Fojtik <mfojtik@packager> - 0.0.1-2
|
90
|
+
- Fixed broken dependencies
|
91
|
+
- Added new launcher for Fedora
|
data/tests/api_test.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'tests/common'
|
2
|
+
|
3
|
+
module DeltacloudUnitTest
|
4
|
+
class ApiTest < Test::Unit::TestCase
|
5
|
+
include Rack::Test::Methods
|
6
|
+
|
7
|
+
def app
|
8
|
+
Sinatra::Application
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_it_returns_entry_points
|
12
|
+
do_xml_request '/api'
|
13
|
+
(last_xml_response/'/api/link').map.size.should > 0
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_it_has_correct_attributes_set
|
17
|
+
do_xml_request '/api'
|
18
|
+
(last_xml_response/'/api/link').each do |link|
|
19
|
+
link.attributes.keys.sort.should == [ 'href', 'rel' ]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_it_responses_to_html
|
24
|
+
do_request '/api', {}, false, { :format => :html }
|
25
|
+
last_response.status.should == 200
|
26
|
+
Nokogiri::HTML(last_response.body).search('html').first.name.should == 'html'
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_it_responses_to_json
|
30
|
+
do_request '/api', {}, false, { :format => :json }
|
31
|
+
last_response.status.should == 200
|
32
|
+
JSON::parse(last_response.body).class.should == Hash
|
33
|
+
JSON::parse(last_response.body)['api'].class.should == Hash
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|