deltacloud-core 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +63 -7
- data/bin/deltacloudd +29 -17
- data/config.ru +5 -3
- data/config/drivers/ec2.yaml +9 -0
- data/config/drivers/google.yaml +3 -0
- data/config/drivers/openstack.yaml +3 -0
- data/deltacloud-core.gemspec +1 -1
- data/lib/cimi/dependencies.rb +62 -0
- data/lib/cimi/helpers/cimi_helper.rb +50 -0
- data/lib/cimi/model.rb +52 -0
- data/lib/cimi/model/action.rb +24 -0
- data/lib/cimi/model/base.rb +249 -0
- data/lib/cimi/model/cloud_entry_point.rb +48 -0
- data/lib/cimi/model/entity_metadata.rb +83 -0
- data/lib/cimi/model/entity_metadata_collection.rb +31 -0
- data/lib/cimi/model/errors.rb +40 -0
- data/lib/cimi/model/machine.rb +227 -0
- data/lib/cimi/model/machine_admin.rb +59 -0
- data/lib/cimi/model/machine_admin_collection.rb +34 -0
- data/lib/cimi/model/machine_collection.rb +34 -0
- data/lib/cimi/model/machine_configuration.rb +67 -0
- data/lib/cimi/model/machine_configuration_collection.rb +34 -0
- data/lib/cimi/model/machine_image.rb +46 -0
- data/lib/cimi/model/machine_image_collection.rb +34 -0
- data/lib/cimi/model/machine_template.rb +41 -0
- data/lib/cimi/model/machine_template_collection.rb +34 -0
- data/lib/cimi/model/network.rb +69 -0
- data/lib/cimi/model/network_collection.rb +34 -0
- data/lib/cimi/model/network_configuration.rb +50 -0
- data/lib/cimi/model/network_configuration_collection.rb +34 -0
- data/lib/cimi/model/network_template.rb +26 -0
- data/lib/cimi/model/schema.rb +277 -0
- data/lib/cimi/model/volume.rb +103 -0
- data/lib/cimi/model/volume_collection.rb +34 -0
- data/lib/cimi/model/volume_configuration.rb +60 -0
- data/lib/cimi/model/volume_configuration_collection.rb +34 -0
- data/lib/cimi/model/volume_image.rb +49 -0
- data/lib/cimi/model/volume_image_collection.rb +34 -0
- data/lib/cimi/model/volume_template.rb +23 -0
- data/lib/cimi/model/volume_template_collection.rb +34 -0
- data/lib/cimi/server.rb +575 -0
- data/lib/deltacloud/base_driver/base_driver.rb +11 -1
- data/lib/deltacloud/core_ext.rb +2 -0
- data/lib/deltacloud/core_ext/array.rb +25 -0
- data/lib/deltacloud/core_ext/hash.rb +7 -0
- data/lib/deltacloud/core_ext/proc.rb +31 -0
- data/lib/deltacloud/core_ext/string.rb +15 -0
- data/lib/deltacloud/drivers/condor/condor_driver.rb +2 -1
- data/lib/deltacloud/drivers/ec2/ec2_driver.rb +32 -10
- data/lib/deltacloud/drivers/eucalyptus/eucalyptus_driver.rb +1 -1
- data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +1 -1
- data/lib/deltacloud/drivers/google/google_driver.rb +233 -0
- data/lib/deltacloud/drivers/mock/data/instances/inst0.yml +7 -2
- data/lib/deltacloud/drivers/mock/data/instances/inst1.yml +7 -2
- data/lib/deltacloud/drivers/mock/data/instances/inst2.yml +7 -2
- data/lib/deltacloud/drivers/mock/mock_client.rb +17 -0
- data/lib/deltacloud/drivers/mock/mock_driver.rb +82 -8
- data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +1 -1
- data/lib/deltacloud/drivers/openstack/openstack_driver.rb +47 -0
- data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +8 -8
- data/lib/deltacloud/drivers/rhevm/rhevm_client.rb +122 -49
- data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +42 -22
- data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +1 -1
- data/lib/deltacloud/drivers/sbc/sbc_driver.rb +3 -2
- data/lib/deltacloud/drivers/terremark/terremark_driver.rb +2 -2
- data/lib/deltacloud/drivers/vsphere/vsphere_client.rb +25 -4
- data/lib/deltacloud/drivers/vsphere/vsphere_driver.rb +35 -12
- data/lib/deltacloud/hardware_profile.rb +34 -10
- data/lib/deltacloud/helpers/application_helper.rb +3 -28
- data/lib/deltacloud/helpers/blob_stream.rb +2 -1
- data/lib/deltacloud/models.rb +2 -0
- data/lib/deltacloud/models/bucket.rb +1 -1
- data/lib/deltacloud/models/image.rb +1 -1
- data/lib/deltacloud/models/instance.rb +2 -1
- data/lib/deltacloud/models/instance_address.rb +56 -0
- data/lib/deltacloud/models/provider.rb +27 -0
- data/{server.rb → lib/deltacloud/server.rb} +72 -14
- data/lib/deltacloud/validation.rb +31 -10
- data/lib/sinatra/rabbit.rb +34 -26
- data/lib/sinatra/rack_accept.rb +5 -5
- data/lib/sinatra/rack_matrix_params.rb +6 -2
- data/lib/sinatra/rack_syslog.rb +3 -3
- data/lib/sinatra/static_assets.rb +1 -1
- data/lib/sinatra/url_for.rb +1 -7
- data/public/images/bread-bg.png +0 -0
- data/public/images/logo-wide.png +0 -0
- data/public/images/topbar-bg.png +0 -0
- data/public/javascripts/application.js +5 -0
- data/public/javascripts/cmwgapp.js +249 -0
- data/public/javascripts/jquery-1.4.2.min.js +154 -0
- data/public/javascripts/jquery.mobile-1.0rc1.min.js +170 -0
- data/public/stylesheets/images/icons-18-black.png +0 -0
- data/public/stylesheets/images/icons-18-white.png +0 -0
- data/public/stylesheets/images/icons-36-black.png +0 -0
- data/public/stylesheets/images/icons-36-white.png +0 -0
- data/public/stylesheets/jquery.mobile-1.0rc1.min.css +12 -0
- data/public/stylesheets/new.css +4 -0
- data/support/fedora/deltacloud-core.init +20 -13
- data/tests/cimi/features/step_definitions/common_steps.rb +59 -0
- data/tests/cimi/features/step_definitions/machine_images_steps.rb +0 -0
- data/tests/cimi/features/step_definitions/machines_steps.rb +99 -0
- data/tests/cimi/features/step_definitions/volumes_steps.rb +115 -0
- data/tests/cimi/features/support/env.rb +53 -0
- data/tests/common.rb +89 -11
- data/tests/core_ext/string.rb +31 -0
- data/tests/drivers/google/api_test.rb +35 -0
- data/tests/drivers/google/buckets_test.rb +116 -0
- data/tests/drivers/google/setup.rb +38 -0
- data/tests/drivers/mock/instances_test.rb +20 -5
- data/tests/drivers/openstack/api_test.rb +41 -0
- data/tests/drivers/openstack/hardware_profiles_test.rb +53 -0
- data/tests/drivers/openstack/images_test.rb +40 -0
- data/tests/drivers/openstack/instances_test.rb +163 -0
- data/tests/drivers/openstack/realms_test.rb +36 -0
- data/tests/drivers/openstack/setup.rb +20 -0
- data/tests/drivers/rackspace/buckets_test.rb +145 -0
- data/tests/drivers/rackspace/setup.rb +3 -3
- data/tests/drivers/rhevm/api_test.rb +1 -1
- data/tests/drivers/rhevm/images_test.rb +2 -2
- data/tests/drivers/rhevm/instances_test.rb +10 -12
- data/tests/drivers/rhevm/realms_test.rb +4 -4
- data/tests/drivers/rhevm/setup.rb +3 -3
- data/tests/rabbit_test.rb +1 -1
- data/views/api/show.html.haml +13 -0
- data/views/cimi/cloudEntryPoint/index.html.haml +5 -0
- data/views/cimi/cloudEntryPoint/index.xml.haml +9 -0
- data/views/cimi/collection/index.html.haml +45 -0
- data/views/cimi/collection/response.xml.haml +3 -0
- data/views/cimi/error.html.haml +31 -0
- data/views/cimi/errors/400.html.haml +41 -0
- data/views/cimi/errors/400.xml.haml +3 -0
- data/views/cimi/errors/401.html.haml +41 -0
- data/views/cimi/errors/401.xml.haml +2 -0
- data/views/cimi/errors/403.html.haml +42 -0
- data/views/cimi/errors/403.xml.haml +2 -0
- data/views/cimi/errors/404.html.haml +29 -0
- data/views/cimi/errors/404.xml.haml +2 -0
- data/views/cimi/errors/405.html.haml +29 -0
- data/views/cimi/errors/405.xml.haml +5 -0
- data/views/cimi/errors/500.html.haml +43 -0
- data/views/cimi/errors/500.xml.haml +6 -0
- data/views/cimi/errors/502.html.haml +43 -0
- data/views/cimi/errors/502.xml.haml +7 -0
- data/views/cimi/errors/backend_capability_failure.html.haml +29 -0
- data/views/cimi/layout.html.haml +32 -0
- data/views/cimi/machine_configurations/show.html.haml +159 -0
- data/views/cimi/machine_configurations/show.xml.haml +27 -0
- data/views/cimi/machine_images/show.html.haml +79 -0
- data/views/cimi/machine_images/show.xml.haml +17 -0
- data/views/cimi/machines/show.html.haml +177 -0
- data/views/cimi/machines/show.xml.haml +28 -0
- data/views/cimi/volumes/show.html.haml +68 -0
- data/views/cimi/volumes/show.xml.haml +17 -0
- data/views/drivers/show.html.haml +10 -5
- data/views/drivers/show.xml.haml +9 -4
- data/views/error.html.haml +2 -2
- data/views/errors/500.xml.haml +7 -1
- data/views/instances/index.html.haml +1 -1
- data/views/instances/new.html.haml +19 -16
- data/views/instances/show.html.haml +7 -2
- data/views/instances/show.xml.haml +8 -7
- data/views/layout.html.haml +2 -2
- data/views/storage_volumes/show.html.haml +1 -1
- metadata +296 -204
- data/public/javascripts/jquery.mobile-1.0b1.min.js +0 -146
- data/public/stylesheets/jquery.mobile-1.0b1.min.css +0 -8
data/lib/deltacloud/models.rb
CHANGED
@@ -20,6 +20,7 @@ require 'deltacloud/models/image'
|
|
20
20
|
require 'deltacloud/models/instance'
|
21
21
|
require 'deltacloud/models/key'
|
22
22
|
require 'deltacloud/models/address'
|
23
|
+
require 'deltacloud/models/instance_address'
|
23
24
|
require 'deltacloud/models/instance_profile'
|
24
25
|
require 'deltacloud/models/storage_snapshot'
|
25
26
|
require 'deltacloud/models/storage_volume'
|
@@ -28,3 +29,4 @@ require 'deltacloud/models/blob'
|
|
28
29
|
require 'deltacloud/models/load_balancer'
|
29
30
|
require 'deltacloud/models/firewall'
|
30
31
|
require 'deltacloud/models/firewall_rule'
|
32
|
+
require 'deltacloud/models/provider'
|
@@ -26,7 +26,7 @@ class Bucket < BaseModel
|
|
26
26
|
h = self.to_hash_original
|
27
27
|
unless blob_list.nil?
|
28
28
|
h[:blob_list] = self.blob_list.collect { |blob| { :id => blob,
|
29
|
-
:href => "#{
|
29
|
+
:href => "#{settings.root_url}/buckets/#{self.id}/#{blob}"}}
|
30
30
|
end
|
31
31
|
return h
|
32
32
|
end
|
@@ -30,7 +30,7 @@ class Image < BaseModel
|
|
30
30
|
h.merge({
|
31
31
|
:actions => [ :create_instance => {
|
32
32
|
:method => 'post',
|
33
|
-
:href => "#{
|
33
|
+
:href => "#{settings.root_url}/instances;image_id=#{self.id}"
|
34
34
|
}]
|
35
35
|
})
|
36
36
|
end
|
@@ -34,6 +34,7 @@ class Instance < BaseModel
|
|
34
34
|
attr_accessor :password
|
35
35
|
attr_accessor :create_image
|
36
36
|
attr_accessor :firewalls
|
37
|
+
attr_accessor :storage_volumes
|
37
38
|
|
38
39
|
def can_create_image?
|
39
40
|
self.create_image
|
@@ -75,7 +76,7 @@ class Instance < BaseModel
|
|
75
76
|
def to_hash
|
76
77
|
h = self.to_hash_original
|
77
78
|
h[:public_addresses] = h[:public_addresses].collect do |address|
|
78
|
-
{ :address => { :type => address_type
|
79
|
+
{ :address => { :type => address.address_type, :value => address } }
|
79
80
|
end
|
80
81
|
h[:actions] = self.actions.collect do |action|
|
81
82
|
{ :"#{action}" => {
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
2
|
+
# contributor license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright ownership. The
|
4
|
+
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
5
|
+
# "License"); you may not use this file except in compliance with the
|
6
|
+
# License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
13
|
+
# License for the specific language governing permissions and limitations
|
14
|
+
# under the License.
|
15
|
+
|
16
|
+
# Model to store the hardware profile applied to an instance together with
|
17
|
+
# any instance-specific overrides
|
18
|
+
|
19
|
+
class InstanceAddress
|
20
|
+
attr_accessor :address
|
21
|
+
attr_accessor :port
|
22
|
+
attr_accessor :address_type
|
23
|
+
|
24
|
+
def initialize(address, opts={})
|
25
|
+
self.address = address
|
26
|
+
self.port = opts[:port] if opts[:port]
|
27
|
+
self.address_type = opts[:type] || :ipv4
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def address_type
|
32
|
+
(address and !address.strip.empty?) ? @address_type : :unavailable
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
return ['VNC', address, port].join(':') if is_vnc?
|
37
|
+
address
|
38
|
+
end
|
39
|
+
|
40
|
+
def is_mac?
|
41
|
+
address_type == :mac
|
42
|
+
end
|
43
|
+
|
44
|
+
def is_ipv4?
|
45
|
+
address_type == :ipv4
|
46
|
+
end
|
47
|
+
|
48
|
+
def is_hostname?
|
49
|
+
address_type == :hostname
|
50
|
+
end
|
51
|
+
|
52
|
+
def is_vnc?
|
53
|
+
address_type == :vnc
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
2
|
+
# contributor license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright ownership. The
|
4
|
+
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
5
|
+
# "License"); you may not use this file except in compliance with the
|
6
|
+
# License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
13
|
+
# License for the specific language governing permissions and limitations
|
14
|
+
# under the License.
|
15
|
+
|
16
|
+
# Model to store the hardware profile applied to an instance together with
|
17
|
+
# any instance-specific overrides
|
18
|
+
|
19
|
+
class Provider < BaseModel
|
20
|
+
attr_accessor :url
|
21
|
+
attr_accessor :name
|
22
|
+
|
23
|
+
def initialize(opts={})
|
24
|
+
super(opts)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -31,7 +31,7 @@ require 'sinatra/rack_date'
|
|
31
31
|
require 'sinatra/rack_matrix_params'
|
32
32
|
require 'sinatra/rack_syslog'
|
33
33
|
|
34
|
-
set :version, '0.
|
34
|
+
set :version, '0.5.0'
|
35
35
|
|
36
36
|
include Deltacloud::Drivers
|
37
37
|
set :drivers, Proc.new { driver_config }
|
@@ -46,8 +46,15 @@ use Rack::MediaType
|
|
46
46
|
use Rack::Date
|
47
47
|
|
48
48
|
configure do
|
49
|
-
set :
|
50
|
-
set :
|
49
|
+
set :root_url, "/api"
|
50
|
+
set :views, File::join($top_srcdir, 'views')
|
51
|
+
# NOTE: Change :public to :public_folder once we update sinatra to 1.3
|
52
|
+
# set :public_folder, File::join($top_srcdir, 'public')
|
53
|
+
if settings.respond_to? :public_folder
|
54
|
+
set :public_folder, File::join($top_srcdir, 'public')
|
55
|
+
else
|
56
|
+
set :public, File::join($top_srcdir, 'public')
|
57
|
+
end
|
51
58
|
# Try to load the driver on startup to fail early if there are issues
|
52
59
|
driver
|
53
60
|
end
|
@@ -87,13 +94,24 @@ after do
|
|
87
94
|
end
|
88
95
|
|
89
96
|
# Redirect to /api
|
90
|
-
get '/' do redirect root_url, 301; end
|
97
|
+
get '/' do redirect settings.root_url, 301; end
|
98
|
+
|
99
|
+
|
100
|
+
# Generate a root route for API docs
|
101
|
+
get "#{settings.root_url}/docs\/?" do
|
102
|
+
respond_to do |format|
|
103
|
+
format.html { haml :'docs/index' }
|
104
|
+
format.xml { haml :'docs/index' }
|
105
|
+
end
|
106
|
+
end
|
91
107
|
|
92
|
-
get "#{
|
108
|
+
get "#{settings.root_url}\/?" do
|
93
109
|
if params[:force_auth]
|
94
110
|
return [401, 'Authentication failed'] unless driver.valid_credentials?(credentials)
|
95
111
|
end
|
96
112
|
@collections = [:drivers] + driver.supported_collections
|
113
|
+
@driver_name = driver.name unless driver.name.to_sym == DRIVER
|
114
|
+
@providers = driver.configured_providers
|
97
115
|
respond_to do |format|
|
98
116
|
format.xml { haml :"api/show" }
|
99
117
|
format.json do
|
@@ -110,6 +128,15 @@ get "#{Sinatra::UrlForHelper::DEFAULT_URI_PREFIX}\/?" do
|
|
110
128
|
end
|
111
129
|
end
|
112
130
|
|
131
|
+
post "#{settings.root_url}\/?" do
|
132
|
+
p = {}
|
133
|
+
["provider", "driver"].each { |k| p[k] = params[k] if params[k] }
|
134
|
+
p.delete("provider") if p["provider"] == "default"
|
135
|
+
q = p.map { |k,v| "#{k}=#{v}" }.join(";")
|
136
|
+
q = ";" + q unless q.empty?
|
137
|
+
redirect "#{settings.root_url}#{q}", 301
|
138
|
+
end
|
139
|
+
|
113
140
|
# Rabbit DSL
|
114
141
|
|
115
142
|
collection :drivers do
|
@@ -136,6 +163,9 @@ EOS
|
|
136
163
|
param :id, :string
|
137
164
|
control do
|
138
165
|
@name = params[:id].to_sym
|
166
|
+
if driver_symbol == @name
|
167
|
+
@providers = driver.providers(credentials) if driver.respond_to? :providers
|
168
|
+
end
|
139
169
|
@driver = settings.drivers[@name]
|
140
170
|
return [404, "Driver #{@name} not found"] unless @driver
|
141
171
|
respond_to do |format|
|
@@ -228,7 +258,7 @@ END
|
|
228
258
|
:description => params[:description]
|
229
259
|
})
|
230
260
|
status 201 # Created
|
231
|
-
response['Location'] = image_url(@
|
261
|
+
response['Location'] = image_url(@image.id)
|
232
262
|
respond_to do |format|
|
233
263
|
format.xml { haml :"images/show" }
|
234
264
|
format.json { convert_to_json(:image, @image) }
|
@@ -293,7 +323,7 @@ collection :instance_states do
|
|
293
323
|
end
|
294
324
|
end
|
295
325
|
|
296
|
-
get "#{
|
326
|
+
get "#{settings.root_url}/instances/:id/run" do
|
297
327
|
@instance = driver.instance(credentials, :id => params[:id])
|
298
328
|
respond_to do |format|
|
299
329
|
format.html { haml :"instances/run_command" }
|
@@ -448,14 +478,32 @@ END
|
|
448
478
|
param :hwp_id, :string, :optional
|
449
479
|
control do
|
450
480
|
@instance = driver.create_instance(credentials, params[:image_id], params)
|
481
|
+
if @instance.kind_of? Array
|
482
|
+
@elements = @instance
|
483
|
+
action_handler = "index"
|
484
|
+
else
|
485
|
+
response['Location'] = instance_url(@instance.id)
|
486
|
+
action_handler = "show"
|
487
|
+
end
|
451
488
|
status 201 # Created
|
452
|
-
response['Location'] = instance_url(@instance.id)
|
453
489
|
respond_to do |format|
|
454
|
-
format.xml { haml :"instances
|
455
|
-
format.json
|
490
|
+
format.xml { haml :"instances/#{action_handler}" }
|
491
|
+
format.json do
|
492
|
+
if @elements
|
493
|
+
convert_to_json(:instances, @elements)
|
494
|
+
else
|
495
|
+
convert_to_json(:instance, @elements)
|
496
|
+
end
|
497
|
+
end
|
456
498
|
format.html do
|
457
|
-
|
458
|
-
|
499
|
+
if @elements
|
500
|
+
haml :"instances/index"
|
501
|
+
elsif @instance and @instance.id
|
502
|
+
response['Location'] = instance_url(@instance.id)
|
503
|
+
redirect instance_url(@instance.id)
|
504
|
+
else
|
505
|
+
redirect instances_url
|
506
|
+
end
|
459
507
|
end
|
460
508
|
end
|
461
509
|
end
|
@@ -651,6 +699,16 @@ collection :storage_volumes do
|
|
651
699
|
end
|
652
700
|
end
|
653
701
|
|
702
|
+
operation :attach_instance, :method=>:get, :member=>true do
|
703
|
+
description "A form to attach a storage volume to an instance"
|
704
|
+
control do
|
705
|
+
@instances = driver.instances(credentials)
|
706
|
+
respond_to do |format|
|
707
|
+
format.html{ haml :"storage_volumes/attach"}
|
708
|
+
end
|
709
|
+
end
|
710
|
+
end
|
711
|
+
|
654
712
|
operation :attach, :method => :post, :member => true do
|
655
713
|
description "Attach storage volume to instance"
|
656
714
|
with_capability :attach_storage_volume
|
@@ -769,7 +827,7 @@ end
|
|
769
827
|
# existing blob
|
770
828
|
NEW_BLOB_FORM_ID = "new_blob_form_d15cfd90"
|
771
829
|
|
772
|
-
get "#{
|
830
|
+
get "#{settings.root_url}/buckets/:bucket/#{NEW_BLOB_FORM_ID}" do
|
773
831
|
@bucket_id = params[:bucket]
|
774
832
|
respond_to do |format|
|
775
833
|
format.html {haml :"blobs/new"}
|
@@ -992,7 +1050,7 @@ collection :buckets do
|
|
992
1050
|
|
993
1051
|
end
|
994
1052
|
|
995
|
-
get "#{
|
1053
|
+
get "#{settings.root_url}/addresses/:id/associate" do
|
996
1054
|
@instances = driver.instances(credentials)
|
997
1055
|
@address = Address::new(:id => params[:id])
|
998
1056
|
respond_to do |format|
|
@@ -16,13 +16,12 @@
|
|
16
16
|
|
17
17
|
module Deltacloud::Validation
|
18
18
|
|
19
|
-
class Failure <
|
19
|
+
class Failure < Deltacloud::ExceptionHandler::DeltacloudException
|
20
20
|
attr_reader :param
|
21
|
-
def initialize(
|
22
|
-
|
23
|
-
|
21
|
+
def initialize(e, message=nil)
|
22
|
+
message ||= e.message
|
23
|
+
super(400, e.class.name, message, [])
|
24
24
|
end
|
25
|
-
|
26
25
|
def name
|
27
26
|
param.name if @param
|
28
27
|
end
|
@@ -46,6 +45,19 @@ module Deltacloud::Validation
|
|
46
45
|
def optional?
|
47
46
|
type.eql?(:optional)
|
48
47
|
end
|
48
|
+
|
49
|
+
def valid_value?(value)
|
50
|
+
true if (options.kind_of?(Range) or options.kind_of?(Array)) and options.include?(value)
|
51
|
+
true if options.kind_of?(String) and not options.empty?
|
52
|
+
end
|
53
|
+
|
54
|
+
def valid_hwp_value?(profile, value)
|
55
|
+
profile.property(@name.to_s.gsub(/^hwp_/, '')).valid?(value)
|
56
|
+
end
|
57
|
+
|
58
|
+
def hwp_property?
|
59
|
+
true if name.to_s =~ /^hwp_(cpu|memory|storage|architecture)/
|
60
|
+
end
|
49
61
|
end
|
50
62
|
|
51
63
|
def param(*args)
|
@@ -72,15 +84,24 @@ module Deltacloud::Validation
|
|
72
84
|
params.each_value { |p| yield p }
|
73
85
|
end
|
74
86
|
|
75
|
-
def validate(all_params, values)
|
76
|
-
all_params.
|
87
|
+
def validate(current_driver, all_params, values, credentials)
|
88
|
+
all_params.each do |key, p|
|
77
89
|
if p.required? and not values[p.name]
|
78
90
|
raise Failure.new(p, "Required parameter #{p.name} not found")
|
79
91
|
end
|
80
|
-
|
81
|
-
|
82
|
-
|
92
|
+
next unless values[p.name]
|
93
|
+
if p.hwp_property?
|
94
|
+
profile = current_driver.hardware_profile(credentials, values['hwp_id'])
|
95
|
+
raise Failure.new(p, "Unknown hardware profile selected #{values['hwp_id']}") unless profile
|
96
|
+
unless p.valid_hwp_value?(profile, values[p.name])
|
97
|
+
raise Failure.new(p, "Hardware profile property #{p.name} has invalid value #{values[p.name]}")
|
98
|
+
end
|
99
|
+
else
|
100
|
+
if not p.options.empty? and p.valid_value?(values[p.name])
|
101
|
+
raise Failure.new(p, "Parameter #{p.name} has value #{values[p.name]} which is not in #{p.options.join(", ")}")
|
102
|
+
end
|
83
103
|
end
|
84
104
|
end
|
85
105
|
end
|
106
|
+
|
86
107
|
end
|
data/lib/sinatra/rabbit.rb
CHANGED
@@ -89,8 +89,8 @@ module Sinatra
|
|
89
89
|
|
90
90
|
def generate_documentation
|
91
91
|
coll, oper = @collection, self
|
92
|
-
Rabbit::routes << [:get, "#{
|
93
|
-
::Sinatra::Application.get("#{
|
92
|
+
Rabbit::routes << [:get, "#{settings.root_url}/docs/#{@collection.name}/#{@name}"]
|
93
|
+
::Sinatra::Application.get("#{settings.root_url}/docs/#{@collection.name}/#{@name}") do
|
94
94
|
@collection, @operation = coll, oper
|
95
95
|
@features = driver.features_for_operation(coll.name, oper.name)
|
96
96
|
respond_to do |format|
|
@@ -102,8 +102,8 @@ module Sinatra
|
|
102
102
|
|
103
103
|
def generate_options
|
104
104
|
current_operation = self
|
105
|
-
Rabbit::routes << [:options, "#{
|
106
|
-
::Sinatra::Application.options("#{
|
105
|
+
Rabbit::routes << [:options, "#{settings.root_url}/#{current_operation.collection.name}/#{current_operation.name}"]
|
106
|
+
::Sinatra::Application.options("#{settings.root_url}/#{current_operation.collection.name}/#{current_operation.name}") do
|
107
107
|
required_params = current_operation.effective_params(driver).collect do |name, validation|
|
108
108
|
name.to_s if validation.type.eql?(:required)
|
109
109
|
end.compact.join(',')
|
@@ -121,7 +121,7 @@ module Sinatra
|
|
121
121
|
@control = Proc.new do
|
122
122
|
op.collection.check_supported(driver)
|
123
123
|
op.check_capability(driver)
|
124
|
-
op.validate(op.effective_params(driver), params)
|
124
|
+
op.validate(driver, op.effective_params(driver), params, credentials)
|
125
125
|
instance_eval(&block)
|
126
126
|
end
|
127
127
|
end
|
@@ -152,8 +152,8 @@ module Sinatra
|
|
152
152
|
end
|
153
153
|
|
154
154
|
def generate
|
155
|
-
Rabbit::routes << [@method, "#{
|
156
|
-
::Sinatra::Application.send(@method, "#{
|
155
|
+
Rabbit::routes << [@method, "#{settings.root_url}/#{path}"]
|
156
|
+
::Sinatra::Application.send(@method, "#{settings.root_url}/#{path}", {}, &@control)
|
157
157
|
# Set up some Rails-like URL helpers
|
158
158
|
if name == :index
|
159
159
|
gen_route "#{@collection.name}_url"
|
@@ -202,11 +202,11 @@ module Sinatra
|
|
202
202
|
class Collection
|
203
203
|
attr_reader :name, :operations, :subcollections
|
204
204
|
|
205
|
-
def initialize(name, &block)
|
205
|
+
def initialize(name, options={}, &block)
|
206
206
|
@name = name
|
207
207
|
@description = ""
|
208
208
|
@operations, @subcollections = {}, {}
|
209
|
-
@global = false
|
209
|
+
@global = options[:global] || false
|
210
210
|
instance_eval(&block) if block_given?
|
211
211
|
generate_documentation
|
212
212
|
generate_head
|
@@ -239,8 +239,8 @@ module Sinatra
|
|
239
239
|
|
240
240
|
def generate_head
|
241
241
|
current_collection = self
|
242
|
-
Rabbit::routes << [:head, "#{
|
243
|
-
::Sinatra::Application.head("#{
|
242
|
+
Rabbit::routes << [:head, "#{settings.root_url}/#{name}"]
|
243
|
+
::Sinatra::Application.head("#{settings.root_url}/#{name}") do
|
244
244
|
methods_allowed = current_collection.operations.collect { |o| o[1].method.to_s.upcase }.uniq.join(',')
|
245
245
|
headers 'Allow' => "HEAD,OPTIONS,#{methods_allowed}"
|
246
246
|
[200, '']
|
@@ -249,8 +249,8 @@ module Sinatra
|
|
249
249
|
|
250
250
|
def generate_options
|
251
251
|
current_collection = self
|
252
|
-
Rabbit::routes << [:options, "#{
|
253
|
-
::Sinatra::Application.options("#{
|
252
|
+
Rabbit::routes << [:options, "#{settings.root_url}/#{name}"]
|
253
|
+
::Sinatra::Application.options("#{settings.root_url}/#{name}") do
|
254
254
|
operations_allowed = current_collection.operations.collect { |o| o[0] }.join(',')
|
255
255
|
headers 'X-Operations-Allowed' => operations_allowed
|
256
256
|
[200, '']
|
@@ -259,8 +259,8 @@ module Sinatra
|
|
259
259
|
|
260
260
|
def generate_documentation
|
261
261
|
coll = self
|
262
|
-
Rabbit::routes << [:get, "#{
|
263
|
-
::Sinatra::Application.get("#{
|
262
|
+
Rabbit::routes << [:get, "#{settings.root_url}/docs/#{@name}"]
|
263
|
+
::Sinatra::Application.get("#{settings.root_url}/docs/#{@name}") do
|
264
264
|
coll.check_supported(driver)
|
265
265
|
@collection = coll
|
266
266
|
@operations = coll.operations
|
@@ -393,14 +393,19 @@ module Sinatra
|
|
393
393
|
collections[name].generate
|
394
394
|
end
|
395
395
|
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
format.xml { haml :'docs/index' }
|
401
|
-
end
|
396
|
+
def global_collection(name, &block)
|
397
|
+
raise DuplicateCollectionException if collections[name]
|
398
|
+
collections[name] = Collection.new(name, { :global => true }, &block)
|
399
|
+
collections[name].generate
|
402
400
|
end
|
403
401
|
|
402
|
+
# Make sure this collection can be accessed, regardless of whether the
|
403
|
+
# driver supports it or not
|
404
|
+
def global_collection(name, &block)
|
405
|
+
raise DuplicateCollectionException if collections[name]
|
406
|
+
collections[name] = Collection.new(name, :global => true, &block)
|
407
|
+
collections[name].generate
|
408
|
+
end
|
404
409
|
end
|
405
410
|
|
406
411
|
module RabbitHelper
|
@@ -423,11 +428,14 @@ module Sinatra
|
|
423
428
|
helpers RabbitHelper
|
424
429
|
end
|
425
430
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
431
|
+
# In Sinatra < 1.2 there was no helper to create OPTIONS route
|
432
|
+
unless Sinatra::Base.respond_to? :options
|
433
|
+
configure do
|
434
|
+
class << Sinatra::Base
|
435
|
+
def options(path, opts={}, &block)
|
436
|
+
route 'OPTIONS', path, opts, &block
|
437
|
+
end
|
430
438
|
end
|
439
|
+
Sinatra::Delegator.delegate :options
|
431
440
|
end
|
432
|
-
Sinatra::Delegator.delegate :options
|
433
441
|
end
|