deltacloud-core 1.0.5 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +10 -2
- data/bin/deltacloudd +10 -10
- data/config.ru +2 -1
- data/config/drivers/digitalocean.yaml +3 -0
- data/deltacloud-core.gemspec +13 -6
- data/lib/cimi/collections.rb +1 -1
- data/lib/cimi/collections/address_templates.rb +27 -3
- data/lib/cimi/collections/addresses.rb +1 -1
- data/lib/cimi/collections/base.rb +1 -0
- data/lib/cimi/collections/cloud_entry_point.rb +4 -0
- data/lib/cimi/collections/credentials.rb +2 -2
- data/lib/cimi/collections/machine_images.rb +20 -0
- data/lib/cimi/collections/machine_templates.rb +72 -0
- data/lib/cimi/collections/machines.rb +50 -41
- data/lib/cimi/collections/network_ports.rb +3 -3
- data/lib/cimi/collections/networks.rb +4 -4
- data/lib/cimi/collections/resource_metadata.rb +1 -1
- data/lib/cimi/collections/volume_configurations.rb +25 -0
- data/lib/cimi/collections/volume_images.rb +21 -1
- data/lib/cimi/collections/volume_templates.rb +69 -0
- data/lib/cimi/collections/volumes.rb +5 -10
- data/lib/cimi/dependencies.rb +0 -1
- data/lib/cimi/helpers.rb +4 -1
- data/lib/cimi/helpers/cimi_helper.rb +62 -0
- data/lib/cimi/helpers/database_helper.rb +95 -0
- data/lib/cimi/models.rb +15 -1
- data/lib/cimi/models/address.rb +10 -5
- data/lib/cimi/models/address_template.rb +67 -3
- data/lib/cimi/models/base.rb +8 -5
- data/lib/cimi/models/cloud_entry_point.rb +6 -1
- data/lib/cimi/models/collection.rb +9 -4
- data/lib/cimi/models/disk.rb +6 -1
- data/lib/cimi/models/errors.rb +8 -0
- data/lib/cimi/models/machine.rb +68 -42
- data/lib/cimi/models/machine_configuration.rb +2 -2
- data/lib/cimi/models/machine_image.rb +41 -6
- data/lib/cimi/models/machine_template.rb +58 -0
- data/lib/cimi/models/machine_volume.rb +51 -3
- data/lib/cimi/models/resource_metadata.rb +88 -25
- data/lib/cimi/models/schema.rb +19 -5
- data/lib/cimi/models/volume.rb +66 -30
- data/lib/cimi/models/volume_configuration.rb +53 -21
- data/lib/cimi/models/volume_image.rb +24 -9
- data/lib/cimi/models/volume_template.rb +61 -0
- data/lib/cimi/server.rb +0 -6
- data/lib/db.rb +82 -0
- data/lib/db/address_template.rb +15 -0
- data/lib/db/entity.rb +22 -0
- data/lib/db/machine_template.rb +10 -0
- data/lib/db/provider.rb +13 -0
- data/lib/db/volume_configuration.rb +10 -0
- data/lib/db/volume_template.rb +10 -0
- data/lib/deltacloud/collections/addresses.rb +1 -1
- data/lib/deltacloud/collections/base.rb +12 -1
- data/lib/deltacloud/collections/buckets.rb +41 -8
- data/lib/deltacloud/collections/drivers.rb +1 -1
- data/lib/deltacloud/collections/firewalls.rb +2 -2
- data/lib/deltacloud/collections/images.rb +1 -1
- data/lib/deltacloud/collections/instances.rb +7 -1
- data/lib/deltacloud/collections/keys.rb +1 -1
- data/lib/deltacloud/collections/load_balancers.rb +4 -4
- data/lib/deltacloud/collections/storage_snapshots.rb +5 -1
- data/lib/deltacloud/collections/storage_volumes.rb +7 -3
- data/lib/deltacloud/drivers/base_driver.rb +10 -9
- data/lib/deltacloud/drivers/cimi_features.rb +42 -0
- data/lib/deltacloud/drivers/digitalocean/digitalocean_driver.rb +307 -0
- data/lib/deltacloud/drivers/ec2/ec2_driver.rb +40 -14
- data/lib/deltacloud/drivers/exceptions.rb +8 -0
- data/lib/deltacloud/drivers/features.rb +19 -2
- data/lib/deltacloud/drivers/fgcp/fgcp_client.rb +11 -0
- data/lib/deltacloud/drivers/fgcp/fgcp_driver.rb +83 -11
- data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +1 -1
- data/lib/deltacloud/drivers/mock/mock_client.rb +2 -4
- data/lib/deltacloud/drivers/mock/mock_driver.rb +29 -0
- data/lib/deltacloud/drivers/openstack/openstack_driver.rb +153 -36
- data/lib/deltacloud/drivers/rackspace/anti_cache_monkey_patch.rb +20 -0
- data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +1 -0
- data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +30 -12
- data/lib/deltacloud/drivers/sbc/sbc_client.rb +0 -1
- data/lib/deltacloud/drivers/sbc/sbc_driver.rb +5 -1
- data/lib/deltacloud/drivers/vsphere/vsphere_client.rb +1 -1
- data/lib/deltacloud/drivers/vsphere/vsphere_driver.rb +19 -9
- data/lib/deltacloud/helpers/blob_stream_helper.rb +42 -3
- data/lib/deltacloud/helpers/deltacloud_helper.rb +31 -14
- data/lib/deltacloud/models/address.rb +9 -0
- data/lib/deltacloud/models/base_model.rb +4 -0
- data/lib/deltacloud/models/blob.rb +12 -0
- data/lib/deltacloud/models/bucket.rb +9 -0
- data/lib/deltacloud/models/firewall.rb +13 -1
- data/lib/deltacloud/models/firewall_rule.rb +14 -0
- data/lib/deltacloud/models/hardware_profile.rb +14 -0
- data/lib/deltacloud/models/image.rb +15 -0
- data/lib/deltacloud/models/instance.rb +40 -1
- data/lib/deltacloud/models/instance_address.rb +9 -0
- data/lib/deltacloud/models/key.rb +15 -0
- data/lib/deltacloud/models/load_balancer.rb +20 -0
- data/lib/deltacloud/models/metric.rb +15 -0
- data/lib/deltacloud/models/provider.rb +8 -0
- data/lib/deltacloud/models/realm.rb +9 -0
- data/lib/deltacloud/models/state_machine.rb +8 -0
- data/lib/deltacloud/models/storage_snapshot.rb +11 -0
- data/lib/deltacloud/models/storage_volume.rb +24 -0
- data/lib/deltacloud/server.rb +1 -3
- data/lib/deltacloud/version.rb +2 -1
- data/lib/deltacloud_rack.rb +1 -1
- data/tests/cimi/db/database_helper_test.rb +190 -0
- data/tests/cimi/db/db_helper.rb +30 -0
- data/tests/cimi/db/schema_test.rb +94 -0
- data/tests/cimi/model/collection_spec.rb +0 -1
- data/tests/cimi/model/machine_spec.rb +17 -0
- data/tests/cimi/spec_helper.rb +3 -2
- data/tests/deltacloud/collections/buckets_collection_test.rb +3 -0
- data/tests/deltacloud/collections/drivers_collection_test.rb +10 -0
- data/tests/deltacloud/collections/hardware_profiles_collection_test.rb +4 -0
- data/tests/deltacloud/collections/images_collection_test.rb +4 -0
- data/tests/deltacloud/collections/instances_collection_test.rb +14 -1
- data/tests/deltacloud/collections/keys_collection_test.rb +4 -0
- data/tests/deltacloud/collections/realms_collection_test.rb +47 -0
- data/tests/deltacloud/collections/storage_snapshots_collection_test.rb +47 -0
- data/tests/deltacloud/collections/storage_volumes_collection_test.rb +47 -0
- data/tests/deltacloud/common.rb +15 -0
- data/tests/deltacloud/deltacloud_helper_test.rb +0 -4
- data/tests/deltacloud/launcher_test.rb +108 -0
- data/tests/drivers/ec2/buckets_test.rb +2 -1
- data/tests/drivers/mock/buckets_test.rb +27 -0
- data/tests/drivers/mock/instances_test.rb +6 -0
- data/tests/drivers/openstack/common.rb +1 -1
- data/tests/drivers/openstack/hardware_profiles_test.rb +2 -1
- data/tests/drivers/openstack/instances_test.rb +18 -17
- data/tests/drivers/rhevm/common.rb +1 -0
- data/tests/drivers/rhevm/images_test.rb +1 -1
- data/tests/drivers/rhevm/instance_test.rb +7 -7
- data/tests/helpers/rack/rack_matrix_params_test.rb +0 -2
- data/tests/test_helper.rb +2 -1
- data/views/errors/403.xml.haml +6 -0
- data/views/errors/409.html.haml +47 -0
- data/views/errors/409.xml.haml +11 -0
- data/views/errors/502.html.haml +6 -5
- data/views/images/show.xml.haml +3 -2
- data/views/instances/new.html.haml +1 -1
- metadata +77 -30
@@ -0,0 +1,20 @@
|
|
1
|
+
# This is a copy of code that has been submitted upstream
|
2
|
+
# https://github.com/rackspace/ruby-cloudservers/pull/22
|
3
|
+
#
|
4
|
+
# Once the pull request is merged we can remove this patch
|
5
|
+
# Also see https://issues.apache.org/jira/browse/DTACLOUD-319
|
6
|
+
|
7
|
+
module CloudServers
|
8
|
+
class Connection
|
9
|
+
|
10
|
+
def list_servers_detail(options = {})
|
11
|
+
anti_cache_param="cacheid=#{Time.now.to_i}"
|
12
|
+
path = CloudServers.paginate(options).empty? ? "#{svrmgmtpath}/servers/detail?#{anti_cache_param}" : "#{svrmgmtpath}/servers/detail?#{CloudServers.paginate(options)}&#{anti_cache_param}"
|
13
|
+
response = csreq("GET",svrmgmthost,path,svrmgmtport,svrmgmtscheme)
|
14
|
+
CloudServers::Exception.raise_exception(response) unless response.code.match(/^20.$/)
|
15
|
+
CloudServers.symbolize_keys(JSON.parse(response.body)["servers"])
|
16
|
+
end
|
17
|
+
alias :servers_detail :list_servers_detail
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -118,9 +118,7 @@ class RhevmDriver < Deltacloud::BaseDriver
|
|
118
118
|
def destroy_image(credentials, image_id)
|
119
119
|
client = new_client(credentials)
|
120
120
|
safely do
|
121
|
-
|
122
|
-
raise "ERROR: Unable to remove image"
|
123
|
-
end
|
121
|
+
client.destroy_template(image_id)
|
124
122
|
end
|
125
123
|
end
|
126
124
|
|
@@ -208,8 +206,13 @@ class RhevmDriver < Deltacloud::BaseDriver
|
|
208
206
|
def new_client(credentials)
|
209
207
|
safely do
|
210
208
|
raise 'No API provider set for this request.' unless api_provider
|
211
|
-
url, datacenter = api_provider.split(';')
|
212
|
-
|
209
|
+
url, datacenter, filtered = api_provider.split(';')
|
210
|
+
if filtered.nil?
|
211
|
+
OVIRT::Client.new(credentials.user, credentials.password, url, datacenter)
|
212
|
+
else
|
213
|
+
filtered_api = filtered.upcase == 'USER'
|
214
|
+
OVIRT::Client.new(credentials.user, credentials.password, url, datacenter, nil, filtered_api)
|
215
|
+
end
|
213
216
|
end
|
214
217
|
end
|
215
218
|
|
@@ -244,14 +247,25 @@ class RhevmDriver < Deltacloud::BaseDriver
|
|
244
247
|
ip = confserver_ip(inst.id)
|
245
248
|
public_addresses = [ InstanceAddress.new(ip) ]
|
246
249
|
end
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
end
|
250
|
+
|
251
|
+
public_addresses += inst.interfaces.map { |interface| InstanceAddress.new(interface.mac, :type => :mac) }
|
252
|
+
|
251
253
|
if inst.vnc
|
252
254
|
public_addresses << InstanceAddress.new(inst.vnc[:address], :port => inst.vnc[:port], :type => :vnc)
|
253
255
|
end
|
256
|
+
|
257
|
+
# Remove 'destroy' operation from list of actions when RHEV-M instance
|
258
|
+
# is suspended or paused.
|
259
|
+
if state == 'PAUSED'
|
260
|
+
actions = instance_actions_for(state = 'STOPPED')
|
261
|
+
actions.delete(:destroy)
|
262
|
+
else
|
263
|
+
actions = instance_actions_for(state)
|
264
|
+
can_create_image = true
|
265
|
+
end
|
266
|
+
|
254
267
|
Instance.new(
|
268
|
+
:actions=>actions,
|
255
269
|
:id => inst.id,
|
256
270
|
:name => inst.name,
|
257
271
|
:state => state,
|
@@ -261,10 +275,9 @@ class RhevmDriver < Deltacloud::BaseDriver
|
|
261
275
|
:launch_time => inst.creation_time,
|
262
276
|
:instance_profile => profile,
|
263
277
|
:hardware_profile_id => profile.id,
|
264
|
-
:actions=>instance_actions_for( state ),
|
265
278
|
:public_addresses => public_addresses,
|
266
279
|
:private_addresses => [],
|
267
|
-
:create_image =>
|
280
|
+
:create_image => can_create_image || false
|
268
281
|
)
|
269
282
|
end
|
270
283
|
|
@@ -283,9 +296,10 @@ class RhevmDriver < Deltacloud::BaseDriver
|
|
283
296
|
return 'PENDING' if ['WAIT_FOR_LAUNCH', 'REBOOT_IN_PROGRESS', 'SAVING_STATE',
|
284
297
|
'RESTORING_STATE', 'POWERING_UP', 'IMAGE_LOCKED', 'SAVING_STATE'].include? state
|
285
298
|
return 'STOPPING' if state == 'POWERING_DOWN'
|
286
|
-
return 'STOPPED' if ['UNASSIGNED', 'DOWN', '
|
299
|
+
return 'STOPPED' if ['UNASSIGNED', 'DOWN', 'NOT_RESPONDING',
|
287
300
|
'IMAGE_ILLEGAL', 'UNKNOWN'].include? state
|
288
301
|
return 'RUNNING' if ['UP', 'MIGRATING_TO', 'MIGRATING_FROM'].include? state
|
302
|
+
return 'PAUSED' if ['PAUSED', 'SUSPENDED'].include? state
|
289
303
|
raise "Unexpected state '#{state}'"
|
290
304
|
end
|
291
305
|
|
@@ -342,6 +356,10 @@ class RhevmDriver < Deltacloud::BaseDriver
|
|
342
356
|
status 404
|
343
357
|
end
|
344
358
|
|
359
|
+
on /(Cannot delete Template. Template is being used)/ do
|
360
|
+
status 409
|
361
|
+
end
|
362
|
+
|
345
363
|
on /(RestClient|RHEVM|OVIRT)/ do
|
346
364
|
status 500
|
347
365
|
end
|
@@ -87,7 +87,11 @@ class SbcDriver < Deltacloud::BaseDriver
|
|
87
87
|
# Map DeltaCloud keywords to SBC
|
88
88
|
body['imageID'] = opts[:image_id]
|
89
89
|
body['location'] = opts[:realm_id] || @last_image['location']
|
90
|
-
|
90
|
+
if opts[:hwp_id]
|
91
|
+
body['instanceType'] = opts[:hwp_id].gsub('-', '/')
|
92
|
+
else
|
93
|
+
body['instanceType'] = @last_image['supportedInstanceTypes'][0]['id']
|
94
|
+
end
|
91
95
|
|
92
96
|
if not body['name']
|
93
97
|
body['name'] = Time.now.to_i.to_s
|
@@ -162,6 +162,7 @@ module Deltacloud::Drivers::Vsphere
|
|
162
162
|
# instance.
|
163
163
|
template_id = vm.config[:extraConfig].select { |k| k.key == 'template_id' }
|
164
164
|
template_id = template_id.first.value unless template_id.empty?
|
165
|
+
|
165
166
|
properties = {
|
166
167
|
:memory => config[:memorySizeMB],
|
167
168
|
:cpus => config[:numCpu],
|
@@ -177,17 +178,15 @@ module Deltacloud::Drivers::Vsphere
|
|
177
178
|
# We're getting IP address from 'vmware guest tools'.
|
178
179
|
# If guest tools are not installed, we return list of MAC addresses
|
179
180
|
# assigned to this instance.
|
180
|
-
public_addresses =
|
181
|
-
if vm.guest[:net].empty?
|
182
|
-
public_addresses
|
183
|
-
else
|
184
|
-
public_addresses = [InstanceAddress.new(vm.guest[:net].first[:ipAddress].first)]
|
181
|
+
public_addresses = vm.macs.values.collect { |mac_address| InstanceAddress.new(mac_address, :type => :mac) }
|
182
|
+
if !vm.guest[:net].empty? and ip_address = vm.guest[:net].first[:ipAddress].first
|
183
|
+
public_addresses += [InstanceAddress.new(ip_address)]
|
185
184
|
end
|
186
185
|
Instance.new(
|
187
186
|
:id => properties[:name],
|
188
187
|
:name => properties[:name],
|
189
188
|
:owner_id => credentials.user,
|
190
|
-
:image_id => template_id,
|
189
|
+
:image_id => template_id.empty? ? nil : template_id,
|
191
190
|
:description => properties[:full_name],
|
192
191
|
:realm_id => realm_id,
|
193
192
|
:state => instance_state,
|
@@ -215,7 +214,7 @@ module Deltacloud::Drivers::Vsphere
|
|
215
214
|
if opts[:hwp_cpu]
|
216
215
|
raise "Invalid CPU value. Must be in integer format" unless valid_cpu_value?(opts[:hwp_cpu])
|
217
216
|
end
|
218
|
-
vm = find_vm(credentials,
|
217
|
+
vm = find_vm(credentials, image_id)
|
219
218
|
raise "ERROR: Could not find the image in given datacenter" unless vm[:instance]
|
220
219
|
# New instance need valid resource pool and datastore to be placed.
|
221
220
|
# For this reason, realm_id **needs** to be set.
|
@@ -291,7 +290,7 @@ module Deltacloud::Drivers::Vsphere
|
|
291
290
|
:config => RbVmomi::VIM.VirtualMachineConfigSpec(machine_config)
|
292
291
|
)
|
293
292
|
instance_profile = InstanceProfile::new('default', :hwp_memory => opts[:hwp_memory], :hwp_cpu => opts[:hwp_cpu])
|
294
|
-
task = vm[:instance].CloneVM_Task(:folder => vm[:instance].parent, :name => opts[:name], :spec => spec)
|
293
|
+
task = vm[:instance].CloneVM_Task(:folder => vm[:instance].parent, :name => opts[:name] || "inst#{Time.now.to_i}", :spec => spec)
|
295
294
|
new_instance = Instance::new(
|
296
295
|
:id => opts[:name],
|
297
296
|
:name => opts[:name],
|
@@ -381,6 +380,10 @@ module Deltacloud::Drivers::Vsphere
|
|
381
380
|
status 504
|
382
381
|
end
|
383
382
|
|
383
|
+
on /missing required parameter name/ do
|
384
|
+
status 400
|
385
|
+
end
|
386
|
+
|
384
387
|
on /Invalid/ do
|
385
388
|
status 400
|
386
389
|
end
|
@@ -410,7 +413,14 @@ module Deltacloud::Drivers::Vsphere
|
|
410
413
|
end
|
411
414
|
|
412
415
|
def host_endpoint
|
413
|
-
endpoint = api_provider
|
416
|
+
endpoint = "#{api_provider}"
|
417
|
+
# We need to have the 'hostname' form in API_PROVIDER, but to be
|
418
|
+
# compatible with other drivers, we allow 'https://vsphere/api' format.
|
419
|
+
# The 'http' and '/.*' parts are however stripped.
|
420
|
+
if endpoint =~ /^http/
|
421
|
+
endpoint.gsub!(/^http(s?):\/\//, '')
|
422
|
+
endpoint.gsub!(/\/.*$/, '')
|
423
|
+
end
|
414
424
|
endpoint || Deltacloud::Drivers::driver_config[:vsphere][:entrypoints]['default']['default']
|
415
425
|
end
|
416
426
|
|
@@ -77,6 +77,43 @@ DELTACLOUD_BLOBMETA_HEADER = /HTTP[-_]X[-_]Deltacloud[-_]Blobmeta[-_]/i
|
|
77
77
|
metadata.gsub_keys(DELTACLOUD_BLOBMETA_HEADER, rename_to)
|
78
78
|
end
|
79
79
|
|
80
|
+
#in the following segment* methods, using context.env["QUERY_STRING"] rather than context.params so it works for both Thin and Sinatra request objects (streaming)
|
81
|
+
def self.segmented_blob(request_context)
|
82
|
+
return true if (request_context.env["HTTP_X_DELTACLOUD_BLOBTYPE"] == 'segmented' || request_context.env["QUERY_STRING"].match(/blob_type=segmented/))
|
83
|
+
false
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.segment_order(request_context)
|
87
|
+
(request_context.env["HTTP_X_DELTACLOUD_SEGMENTORDER"] || request_context.env["QUERY_STRING"].match(/segment_order=(\w)*/){|m| m[0].split("=").pop})
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.segmented_blob_id(request_context)
|
91
|
+
(request_context.env["HTTP_X_DELTACLOUD_SEGMENTEDBLOB"] || request_context.env["QUERY_STRING"].match(/segmented_blob=(\w)*/){|m| m[0].split("=").pop})
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.segmented_blob_op_type(request_context)
|
95
|
+
is_segmented = segmented_blob(request_context)
|
96
|
+
blob_id = segmented_blob_id(request_context)
|
97
|
+
segment_order = segment_order(request_context)
|
98
|
+
#if blob_type=segmented AND segmented_blob_id AND segment_order then it is a "SEGMENT"
|
99
|
+
#if blob_type=segmented AND segmented_blob_id then it is a "FINALIZE"
|
100
|
+
#if blob_type=segmented then it is "INIT"
|
101
|
+
return "segment" if (is_segmented && blob_id && segment_order)
|
102
|
+
return "finalize" if (is_segmented && blob_id)
|
103
|
+
return "init" if is_segmented
|
104
|
+
nil # should explode something instead
|
105
|
+
end
|
106
|
+
|
107
|
+
#in "1=abc , 2=def , 3=ghi"
|
108
|
+
#out {"1"=>"abc", "2"=>"def", "3"=>"ghi"}
|
109
|
+
def self.extract_segmented_blob_manifest(request)
|
110
|
+
manifest_hash = request.body.read.split(",").inject({}) do |res,current|
|
111
|
+
k,v=current.strip.split("=")
|
112
|
+
res[k]=v
|
113
|
+
res
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
80
117
|
end
|
81
118
|
|
82
119
|
#Monkey patch for streaming blobs:
|
@@ -158,11 +195,10 @@ class BlobStreamIO
|
|
158
195
|
@content_length = request.env['CONTENT_LENGTH']
|
159
196
|
@http, provider_request = Deltacloud::API.driver.blob_stream_connection({:user=>user,
|
160
197
|
:password=>password, :bucket=>bucket, :blob=>blob, :metadata=> user_meta,
|
161
|
-
:content_type=>content_type, :content_length=>@content_length })
|
198
|
+
:content_type=>content_type, :content_length=>@content_length, :context=>request })
|
162
199
|
@content_length = @content_length.to_i #for comparison of size in '<< (data)'
|
163
200
|
@sock = @http.request(provider_request, nil, true)
|
164
201
|
end
|
165
|
-
|
166
202
|
def << (data)
|
167
203
|
@sock.write(data)
|
168
204
|
@size += data.length
|
@@ -170,6 +206,9 @@ class BlobStreamIO
|
|
170
206
|
result = @http.end_request
|
171
207
|
if result.is_a?(Net::HTTPSuccess)
|
172
208
|
@client_request.env["BLOB_SUCCESS"] = "true"
|
209
|
+
if BlobHelper.segmented_blob_op_type(@client_request) == "segment"
|
210
|
+
@client_request.env["BLOB_SEGMENT_ID"] = Deltacloud::API.driver.blob_segment_id(@client_request, result)
|
211
|
+
end
|
173
212
|
else
|
174
213
|
@client_request.env["BLOB_FAIL"] = result.body
|
175
214
|
end
|
@@ -195,7 +234,7 @@ class BlobStreamIO
|
|
195
234
|
private
|
196
235
|
|
197
236
|
def parse_bucket_blob(request_string)
|
198
|
-
array = request_string.split("/")
|
237
|
+
array = request_string.gsub(/(&\w*=\w*)*$/, "").split("/")
|
199
238
|
blob = array.pop
|
200
239
|
bucket = array.pop
|
201
240
|
return bucket, blob
|
@@ -18,6 +18,31 @@ module Deltacloud::Helpers
|
|
18
18
|
|
19
19
|
require 'benchmark'
|
20
20
|
|
21
|
+
def collections_to_json(collections)
|
22
|
+
r = {
|
23
|
+
:version => settings.version,
|
24
|
+
:driver => driver_symbol,
|
25
|
+
:provider => Thread.current[:provider] || ENV['API_PROVIDER'],
|
26
|
+
:links => collections.map { |c|
|
27
|
+
{
|
28
|
+
:rel => c.collection_name,
|
29
|
+
:href => self.send(:"#{c.collection_name}_url"),
|
30
|
+
:features => c.features.select { |f| driver.class.has_feature?(c.collection_name, f.name) }.map { |f|
|
31
|
+
f.operations.map { |o|
|
32
|
+
{ :name => f.name, :rel => o.name, :params => o.params_array, :constraints => constraints_hash_for(c.collection_name, f.name) }
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
r[:provider] ||= 'default'
|
39
|
+
JSON::dump(:api => r)
|
40
|
+
end
|
41
|
+
|
42
|
+
def constraints_hash_for(collection_name, feature_name)
|
43
|
+
driver.class.constraints(:collection => collection_name, :feature => feature_name).inject({}) { |r, v| r[v[0]]=v[1];r }
|
44
|
+
end
|
45
|
+
|
21
46
|
def request_headers
|
22
47
|
env.inject({}){|acc, (k,v)| acc[$1.downcase] = v if k =~ /^http_(.*)/i; acc}
|
23
48
|
end
|
@@ -48,22 +73,13 @@ module Deltacloud::Helpers
|
|
48
73
|
respond_to do |format|
|
49
74
|
format.html { haml :"#{model}/index" }
|
50
75
|
format.xml { haml :"#{model}/index" }
|
51
|
-
format.json { @
|
76
|
+
format.json { JSON::dump({ model => @elements.map { |el| el.to_hash(self) }}) }
|
52
77
|
end
|
53
78
|
else
|
54
79
|
report_error(@exception.respond_to?(:code) ? @exception.code : 500)
|
55
80
|
end
|
56
81
|
end
|
57
82
|
|
58
|
-
def xml_to_json(model)
|
59
|
-
@media_type = :xml
|
60
|
-
to_json(haml(:"#{model}"))
|
61
|
-
end
|
62
|
-
|
63
|
-
def to_json(xml)
|
64
|
-
Crack::XML.parse(xml).to_json
|
65
|
-
end
|
66
|
-
|
67
83
|
def show(model)
|
68
84
|
@benchmark = Benchmark.measure do
|
69
85
|
@element = driver.send(model, credentials, { :id => params[:id]} )
|
@@ -74,7 +90,7 @@ module Deltacloud::Helpers
|
|
74
90
|
respond_to do |format|
|
75
91
|
format.html { haml :"#{model.to_s.pluralize}/show" }
|
76
92
|
format.xml { haml :"#{model.to_s.pluralize}/show" }
|
77
|
-
format.json {
|
93
|
+
format.json { JSON::dump(model => @element.to_hash(self)) }
|
78
94
|
end
|
79
95
|
else
|
80
96
|
report_error(404)
|
@@ -101,7 +117,7 @@ module Deltacloud::Helpers
|
|
101
117
|
response.status = @code
|
102
118
|
|
103
119
|
backtrace = (@error.respond_to?(:backtrace) and !@error.backtrace.nil?) ?
|
104
|
-
"\n\n#{@error.backtrace[0..
|
120
|
+
"\n\n#{@error.backtrace[0..20].join("\n")}\n\n" : ''
|
105
121
|
|
106
122
|
if @code.to_s =~ /5(\d+)/
|
107
123
|
log.error(@code.to_s) { "[#{@error.class.to_s}] #{message}#{backtrace}" }
|
@@ -109,7 +125,7 @@ module Deltacloud::Helpers
|
|
109
125
|
|
110
126
|
respond_to do |format|
|
111
127
|
format.xml { haml :"errors/#{@code || @error.code}", :layout => false }
|
112
|
-
format.json {
|
128
|
+
format.json { JSON::dump({ :code => @code || @error.code, :message => message, :error => @error.class.name }) }
|
113
129
|
format.html {
|
114
130
|
begin
|
115
131
|
haml :"errors/#{@code || @error.code}", :layout => :error
|
@@ -151,7 +167,7 @@ module Deltacloud::Helpers
|
|
151
167
|
response = respond_to do |format|
|
152
168
|
format.xml { haml :"instances/show" }
|
153
169
|
format.html { haml :"instances/show" }
|
154
|
-
format.json {
|
170
|
+
format.json { JSON::dump(@instance.to_hash(self)) }
|
155
171
|
end
|
156
172
|
halt 202, response
|
157
173
|
end
|
@@ -245,6 +261,7 @@ module Deltacloud::Helpers
|
|
245
261
|
when 404; { :message => "Not Found" }
|
246
262
|
when 405; { :message => "Method Not Allowed" }
|
247
263
|
when 406; { :message => "Not Acceptable" }
|
264
|
+
when 409; { :message => "Resource Conflict" }
|
248
265
|
when 500; { :message => "Internal Server Error" }
|
249
266
|
when 502; { :message => "Backend Server Error" }
|
250
267
|
when 504; { :message => "Gateway Timeout" }
|
@@ -24,4 +24,16 @@ class Blob < BaseModel
|
|
24
24
|
attr_accessor :content
|
25
25
|
attr_accessor :user_metadata
|
26
26
|
|
27
|
+
def to_hash(context)
|
28
|
+
{
|
29
|
+
:id => self.id,
|
30
|
+
:bucket => { :rel => :bucket, :href => context.bucket_url(bucket), :id => bucket },
|
31
|
+
:content_length => content_length,
|
32
|
+
:content_type => content_type,
|
33
|
+
:last_modified => last_modified,
|
34
|
+
:content => content,
|
35
|
+
:user_metadata => user_metadata
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
27
39
|
end
|
@@ -24,4 +24,13 @@ class Bucket < BaseModel
|
|
24
24
|
@blob_list || []
|
25
25
|
end
|
26
26
|
|
27
|
+
def to_hash(context)
|
28
|
+
{
|
29
|
+
:id => self.id,
|
30
|
+
:name => name,
|
31
|
+
:size => size,
|
32
|
+
:blob_list => blob_list.map { |b| { :rel => :blob, :href => context.url("/buckets/#{self.id}/#{b}"), :id => b }}
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
27
36
|
end
|