deltacloud-core 0.1.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/DISCLAIMER +8 -0
- data/{COPYING → LICENSE} +0 -0
- data/NOTICE +13 -0
- data/Rakefile +50 -51
- data/bin/deltacloudd +8 -1
- data/config.ru +0 -2
- data/config/drivers.yaml +48 -0
- data/deltacloud-core.gemspec +75 -0
- data/deltacloud.rb +3 -2
- data/lib/deltacloud/backend_capability.rb +15 -3
- data/lib/deltacloud/base_driver.rb +0 -2
- data/lib/deltacloud/base_driver/base_driver.rb +85 -89
- data/lib/deltacloud/base_driver/features.rb +61 -7
- data/lib/deltacloud/base_driver/mock_driver.rb +42 -43
- data/lib/deltacloud/core_ext.rb +18 -0
- data/lib/deltacloud/core_ext/integer.rb +31 -0
- data/lib/deltacloud/core_ext/string.rb +50 -0
- data/lib/deltacloud/drivers/azure/azure_driver.rb +71 -22
- data/lib/deltacloud/drivers/ec2/ec2_driver.rb +641 -584
- data/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb +0 -2
- data/lib/deltacloud/drivers/eucalyptus/eucalyptus_driver.rb +167 -0
- data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +39 -1
- data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +41 -25
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob1.yml +6 -3
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob2.yml +6 -3
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob3.yml +4 -2
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob4.yml +5 -2
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob5.yml +4 -2
- data/lib/deltacloud/drivers/mock/data/instances/inst0.yml +1 -0
- data/lib/deltacloud/drivers/mock/data/instances/inst1.yml +1 -0
- data/lib/deltacloud/drivers/mock/data/instances/inst2.yml +1 -0
- data/lib/deltacloud/drivers/mock/data/storage_volumes/vol1.yml +1 -0
- data/lib/deltacloud/drivers/mock/data/storage_volumes/vol2.yml +1 -0
- data/lib/deltacloud/drivers/mock/data/storage_volumes/vol3.yml +1 -0
- data/lib/deltacloud/drivers/mock/mock_driver.rb +138 -30
- data/lib/deltacloud/drivers/opennebula/cloud_client.rb +13 -15
- data/lib/deltacloud/drivers/opennebula/occi_client.rb +13 -15
- data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +13 -15
- data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +224 -113
- data/lib/deltacloud/drivers/rhevm/rhevm_client.rb +332 -0
- data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +221 -170
- data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +0 -1
- data/lib/deltacloud/drivers/sbc/sbc_client.rb +247 -0
- data/lib/deltacloud/drivers/sbc/sbc_driver.rb +297 -0
- data/lib/deltacloud/drivers/terremark/terremark_driver.rb +0 -2
- data/lib/deltacloud/hardware_profile.rb +1 -3
- data/lib/deltacloud/helpers.rb +0 -2
- data/lib/deltacloud/helpers/application_helper.rb +86 -12
- data/lib/deltacloud/helpers/blob_stream.rb +19 -2
- data/lib/deltacloud/helpers/conversion_helper.rb +0 -2
- data/lib/deltacloud/helpers/hardware_profiles_helper.rb +0 -2
- data/lib/deltacloud/method_serializer.rb +0 -2
- data/lib/deltacloud/models/base_model.rb +0 -2
- data/lib/deltacloud/models/blob.rb +1 -2
- data/lib/deltacloud/models/bucket.rb +0 -2
- data/lib/deltacloud/models/image.rb +0 -2
- data/lib/deltacloud/models/instance.rb +19 -2
- data/lib/deltacloud/models/instance_profile.rb +4 -2
- data/lib/deltacloud/models/key.rb +0 -2
- data/lib/deltacloud/models/load_balancer.rb +0 -2
- data/lib/deltacloud/models/realm.rb +0 -2
- data/lib/deltacloud/models/storage_snapshot.rb +0 -2
- data/lib/deltacloud/models/storage_volume.rb +4 -2
- data/lib/deltacloud/runner.rb +132 -0
- data/lib/deltacloud/state_machine.rb +0 -2
- data/lib/deltacloud/validation.rb +9 -7
- data/lib/drivers.rb +36 -48
- data/lib/sinatra/accept_media_types.rb +26 -0
- data/lib/sinatra/lazy_auth.rb +16 -0
- data/lib/sinatra/rabbit.rb +112 -54
- data/lib/sinatra/rack_driver_select.rb +50 -16
- data/lib/sinatra/rack_etag.rb +79 -0
- data/lib/sinatra/rack_matrix_params.rb +84 -0
- data/lib/sinatra/rack_runtime.rb +47 -0
- data/lib/sinatra/static_assets.rb +16 -0
- data/lib/sinatra/url_for.rb +31 -4
- data/public/favicon.ico +0 -0
- data/public/images/bread-bg.png +0 -0
- data/public/images/error.png +0 -0
- data/public/images/pending.png +0 -0
- data/public/images/running.png +0 -0
- data/public/images/stopped.png +0 -0
- data/public/javascripts/application.js +35 -0
- data/public/stylesheets/compiled/application.css +59 -5
- data/public/stylesheets/compiled/screen.css +1 -1
- data/server.rb +293 -29
- data/support/fedora/deltacloud-core +78 -0
- data/support/fedora/deltacloud-core.spec +143 -0
- data/support/fedora/deltacloudd +78 -18
- data/support/fedora/rubygem-deltacloud-core.spec +76 -40
- data/tests/common.rb +172 -0
- data/tests/drivers/mock/api_test.rb +133 -0
- data/tests/drivers/mock/hardware_profiles_test.rb +134 -0
- data/tests/drivers/mock/images_test.rb +126 -0
- data/tests/drivers/mock/instance_states_test.rb +71 -0
- data/tests/drivers/mock/instances_test.rb +236 -0
- data/tests/drivers/mock/realms_test.rb +93 -0
- data/tests/drivers/mock/setup.rb +3 -0
- data/tests/drivers/mock/url_for_test.rb +67 -0
- data/tests/drivers/rackspace/api_test.rb +41 -0
- data/tests/drivers/rackspace/hardware_profiles_test.rb +53 -0
- data/tests/drivers/rackspace/images_test.rb +40 -0
- data/tests/drivers/rackspace/instances_test.rb +161 -0
- data/tests/drivers/rackspace/realms_test.rb +36 -0
- data/tests/drivers/rackspace/setup.rb +14 -0
- data/tests/drivers/rhevm/api_test.rb +39 -0
- data/tests/drivers/rhevm/hardware_profiles_test.rb +53 -0
- data/tests/drivers/rhevm/images_test.rb +42 -0
- data/tests/drivers/rhevm/instances_test.rb +179 -0
- data/tests/drivers/rhevm/realms_test.rb +35 -0
- data/tests/drivers/rhevm/setup.rb +14 -0
- data/tests/rabbit_test.rb +52 -0
- data/views/api/show.html.haml +2 -5
- data/views/blobs/new.html.haml +17 -1
- data/views/blobs/show.html.haml +6 -0
- data/views/blobs/show.xml.haml +5 -1
- data/views/buckets/index.html.haml +1 -12
- data/views/buckets/index.xml.haml +3 -5
- data/views/docs/operation.html.haml +23 -11
- data/views/drivers/index.html.haml +15 -0
- data/views/drivers/index.xml.haml +7 -0
- data/views/drivers/show.html.haml +20 -0
- data/views/drivers/show.xml.haml +7 -0
- data/views/error.html.haml +31 -0
- data/views/errors/auth_exception.xml.haml +2 -1
- data/views/errors/backend_capability_failure.xml.haml +2 -1
- data/views/errors/backend_error.html.haml +3 -0
- data/views/errors/backend_error.xml.haml +2 -2
- data/views/errors/validation_failure.xml.haml +3 -2
- data/views/images/index.html.haml +1 -6
- data/views/images/index.xml.haml +2 -0
- data/views/images/new.html.haml +14 -0
- data/views/images/show.xml.haml +2 -0
- data/views/instances/index.html.haml +8 -6
- data/views/instances/index.xml.haml +4 -0
- data/views/instances/new.html.haml +40 -11
- data/views/instances/run.html.haml +9 -0
- data/views/instances/run.xml.haml +7 -0
- data/views/instances/run_command.html.haml +16 -0
- data/views/instances/show.html.haml +14 -0
- data/views/instances/show.xml.haml +12 -4
- data/views/layout.html.haml +7 -2
- data/views/load_balancers/index.html.haml +1 -1
- data/views/load_balancers/new.html.haml +2 -2
- data/views/load_balancers/show.html.haml +1 -1
- data/views/storage_snapshots/index.html.haml +3 -0
- data/views/storage_snapshots/new.html.haml +9 -0
- data/views/storage_volumes/attach.html.haml +20 -0
- data/views/storage_volumes/index.html.haml +16 -1
- data/views/storage_volumes/index.xml.haml +1 -10
- data/views/storage_volumes/new.html.haml +17 -0
- data/views/storage_volumes/show.html.haml +8 -0
- data/views/storage_volumes/show.xml.haml +25 -3
- metadata +197 -127
- data/lib/deltacloud/drivers/rackspace/rackspace_client.rb +0 -130
- data/parse.rb +0 -7
- data/test.rb +0 -3
- data/views/api/drivers.xml.haml +0 -6
@@ -1,6 +1,4 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (C) 2009,2010 Red Hat, Inc.
|
3
|
-
#
|
4
2
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
5
3
|
# contributor license agreements. See the NOTICE file distributed with
|
6
4
|
# this work for additional information regarding copyright ownership. The
|
@@ -37,8 +35,12 @@ module Deltacloud::Validation
|
|
37
35
|
@name = args[0]
|
38
36
|
@klass = args[1] || :string
|
39
37
|
@type = args[2] || :optional
|
40
|
-
|
41
|
-
|
38
|
+
if args[3] and args[3].class.eql?(String)
|
39
|
+
@description = args[3]
|
40
|
+
@options = []
|
41
|
+
end
|
42
|
+
@options ||= args[3] || []
|
43
|
+
@description ||= args[4] || ''
|
42
44
|
end
|
43
45
|
|
44
46
|
def required?
|
@@ -51,7 +53,7 @@ module Deltacloud::Validation
|
|
51
53
|
end
|
52
54
|
|
53
55
|
def param(*args)
|
54
|
-
raise
|
56
|
+
raise "Duplicate param #{args[0]} #{params.inspect} #{self.class.name}" if params[args[0]]
|
55
57
|
p = Param.new(args)
|
56
58
|
params[p.name] = p
|
57
59
|
end
|
@@ -74,8 +76,8 @@ module Deltacloud::Validation
|
|
74
76
|
params.each_value { |p| yield p }
|
75
77
|
end
|
76
78
|
|
77
|
-
def validate(values)
|
78
|
-
|
79
|
+
def validate(all_params, values)
|
80
|
+
all_params.each_value do |p|
|
79
81
|
if p.required? and not values[p.name]
|
80
82
|
raise Failure.new(p, "Required parameter #{p.name} not found")
|
81
83
|
end
|
data/lib/drivers.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# Copyright (C) 2009, 2010 Red Hat, Inc.
|
2
|
-
#
|
3
1
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
4
2
|
# contributor license agreements. See the NOTICE file distributed with
|
5
3
|
# this work for additional information regarding copyright ownership. The
|
@@ -16,62 +14,52 @@
|
|
16
14
|
# under the License.
|
17
15
|
|
18
16
|
module Deltacloud
|
19
|
-
DRIVERS = {
|
20
|
-
:ec2 => { :name => "EC2" },
|
21
|
-
:rackspace => { :name => "Rackspace" },
|
22
|
-
:gogrid => { :name => "Gogrid" },
|
23
|
-
:rhevm => { :name => "RHEVM" },
|
24
|
-
:rimuhosting => { :name => "RimuHosting"},
|
25
|
-
:opennebula => { :name => "Opennebula", :class => "OpennebulaDriver" },
|
26
|
-
:terremark => { :name => "Terremark"},
|
27
|
-
:azure => { :name => "Azure" },
|
28
|
-
:mock => { :name => "Mock" }
|
29
|
-
}
|
30
17
|
|
31
|
-
|
32
|
-
:hardware_profiles,
|
33
|
-
:images,
|
34
|
-
:instances,
|
35
|
-
:instance_states,
|
36
|
-
:realms,
|
37
|
-
:storage_volumes,
|
38
|
-
:storage_snapshots
|
39
|
-
]
|
18
|
+
module Drivers
|
40
19
|
|
41
|
-
|
20
|
+
require 'yaml'
|
42
21
|
|
43
|
-
|
44
|
-
|
45
|
-
|
22
|
+
DEFAULT_COLLECTIONS = [
|
23
|
+
:hardware_profiles,
|
24
|
+
:images,
|
25
|
+
:instances,
|
26
|
+
:instance_states,
|
27
|
+
:realms,
|
28
|
+
:storage_volumes,
|
29
|
+
:storage_snapshots
|
30
|
+
]
|
46
31
|
|
47
|
-
|
48
|
-
DRIVERS[:"#{driver_symbol}"][:name]
|
49
|
-
end
|
32
|
+
DRIVER=ENV['API_DRIVER'] ? ENV['API_DRIVER'].to_sym : :mock
|
50
33
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
34
|
+
def driver_config
|
35
|
+
YAML::load(File.read(File.join(File.dirname(__FILE__), '..', 'config', 'drivers.yaml')))
|
36
|
+
end
|
55
37
|
|
56
|
-
|
57
|
-
|
58
|
-
|
38
|
+
def driver_symbol
|
39
|
+
(Thread.current[:driver] || DRIVER).to_sym
|
40
|
+
end
|
59
41
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
42
|
+
def driver_name
|
43
|
+
driver_config[:"#{driver_symbol}"][:name]
|
44
|
+
end
|
64
45
|
|
65
|
-
|
66
|
-
|
67
|
-
|
46
|
+
def driver_class
|
47
|
+
basename = driver_config[:"#{driver_symbol}"][:class] || "#{driver_name}Driver"
|
48
|
+
Deltacloud::Drivers.const_get(driver_name).const_get(basename)
|
49
|
+
end
|
68
50
|
|
69
|
-
|
70
|
-
|
51
|
+
def driver_source_name
|
52
|
+
File.join("deltacloud", "drivers", "#{driver_symbol}", "#{driver_symbol}_driver.rb")
|
71
53
|
end
|
72
54
|
|
73
|
-
|
55
|
+
def driver_mock_source_name
|
56
|
+
return File.join('deltacloud', 'drivers', "#{driver_symbol}",
|
57
|
+
"#{driver_symbol}_driver.rb") if driver_name.eql? 'Mock'
|
58
|
+
end
|
59
|
+
|
60
|
+
def driver
|
61
|
+
require driver_source_name
|
62
|
+
@driver ||= driver_class.new
|
63
|
+
end
|
74
64
|
end
|
75
65
|
end
|
76
|
-
|
77
|
-
include Deltacloud
|
@@ -1,3 +1,29 @@
|
|
1
|
+
#
|
2
|
+
# Based on https://github.com/mynyml/rack-accept-media-types
|
3
|
+
# Commit 3d0f38882a466cc72043
|
4
|
+
#
|
5
|
+
# Original license:
|
6
|
+
# Copyright (C) 2009 Martin Aumont (mynyml)
|
7
|
+
#
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
9
|
+
# copy of this software and associated documentation files (the
|
10
|
+
# "Software"), to deal in the Software without restriction, including
|
11
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
12
|
+
# distribute, sublicense, and/or sell copies of the Software, and to permit
|
13
|
+
# persons to whom the Software is furnished to do so, subject to the
|
14
|
+
# following conditions:
|
15
|
+
#
|
16
|
+
# The above copyright notice and this permission notice shall be included
|
17
|
+
# in all copies or substantial portions of the Software.
|
18
|
+
#
|
19
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
20
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
21
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
22
|
+
# NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
23
|
+
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
24
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
25
|
+
# USE OR OTHER DEALINGS IN THE SOFTWARE.
|
26
|
+
|
1
27
|
module Rack
|
2
28
|
class Request
|
3
29
|
# The media types of the HTTP_ACCEPT header ordered according to their
|
data/lib/sinatra/lazy_auth.rb
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
#
|
2
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
3
|
+
# contributor license agreements. See the NOTICE file distributed with
|
4
|
+
# this work for additional information regarding copyright ownership. The
|
5
|
+
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance with the
|
7
|
+
# License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
13
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
14
|
+
# License for the specific language governing permissions and limitations
|
15
|
+
# under the License.
|
16
|
+
|
1
17
|
require 'sinatra/base'
|
2
18
|
|
3
19
|
# Lazy Basic HTTP authentication. Authentication is only forced when the
|
data/lib/sinatra/rabbit.rb
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
#
|
2
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
3
|
+
# contributor license agreements. See the NOTICE file distributed with
|
4
|
+
# this work for additional information regarding copyright ownership. The
|
5
|
+
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance with the
|
7
|
+
# License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
13
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
14
|
+
# License for the specific language governing permissions and limitations
|
15
|
+
# under the License.
|
16
|
+
|
1
17
|
require 'sinatra/base'
|
2
18
|
require 'sinatra/url_for'
|
3
19
|
require 'deltacloud/validation'
|
@@ -10,9 +26,10 @@ module Sinatra
|
|
10
26
|
class DuplicateParamException < Exception; end
|
11
27
|
class DuplicateOperationException < Exception; end
|
12
28
|
class DuplicateCollectionException < Exception; end
|
29
|
+
class UnsupportedCollectionException < Exception; end
|
13
30
|
|
14
31
|
class Operation
|
15
|
-
attr_reader :name, :method
|
32
|
+
attr_reader :name, :method, :collection
|
16
33
|
|
17
34
|
include ::Deltacloud::BackendCapability
|
18
35
|
include ::Deltacloud::Validation
|
@@ -35,6 +52,11 @@ module Sinatra
|
|
35
52
|
@description = ""
|
36
53
|
instance_eval(&block) if block_given?
|
37
54
|
generate_documentation
|
55
|
+
generate_options
|
56
|
+
end
|
57
|
+
|
58
|
+
def http_method
|
59
|
+
@method
|
38
60
|
end
|
39
61
|
|
40
62
|
def standard?
|
@@ -50,6 +72,7 @@ module Sinatra
|
|
50
72
|
coll, oper = @collection, self
|
51
73
|
::Sinatra::Application.get("/api/docs/#{@collection.name}/#{@name}") do
|
52
74
|
@collection, @operation = coll, oper
|
75
|
+
@features = driver.features_for_operation(coll.name, oper.name)
|
53
76
|
respond_to do |format|
|
54
77
|
format.html { haml :'docs/operation' }
|
55
78
|
format.xml { haml :'docs/operation' }
|
@@ -57,11 +80,27 @@ module Sinatra
|
|
57
80
|
end
|
58
81
|
end
|
59
82
|
|
83
|
+
def generate_options
|
84
|
+
current_operation = self
|
85
|
+
::Sinatra::Application.options("/api/#{current_operation.collection.name}/#{current_operation.name}") do
|
86
|
+
required_params = current_operation.effective_params(driver).collect do |name, validation|
|
87
|
+
name.to_s if validation.type.eql?(:required)
|
88
|
+
end.compact.join(',')
|
89
|
+
optional_params = current_operation.effective_params(driver).collect do |name, validation|
|
90
|
+
name.to_s if validation.type.eql?(:optional)
|
91
|
+
end.compact.join(',')
|
92
|
+
headers 'X-Required-Parameters' => required_params
|
93
|
+
headers 'X-Optional-Parameters' => optional_params
|
94
|
+
[200, '']
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
60
98
|
def control(&block)
|
61
99
|
op = self
|
62
100
|
@control = Proc.new do
|
63
|
-
op.
|
64
|
-
op.
|
101
|
+
op.collection.check_supported(driver)
|
102
|
+
op.check_capability(driver)
|
103
|
+
op.validate(op.effective_params(driver), params)
|
65
104
|
instance_eval(&block)
|
66
105
|
end
|
67
106
|
end
|
@@ -72,7 +111,7 @@ module Sinatra
|
|
72
111
|
end
|
73
112
|
|
74
113
|
def path(args = {})
|
75
|
-
l_prefix = args[:prefix]
|
114
|
+
l_prefix = args[:prefix] || prefix
|
76
115
|
if @member
|
77
116
|
if standard?
|
78
117
|
"#{l_prefix}/#{@collection.name}/:id"
|
@@ -96,6 +135,24 @@ module Sinatra
|
|
96
135
|
end
|
97
136
|
end
|
98
137
|
|
138
|
+
# Return a hash of all params, the params statically defined for this
|
139
|
+
# operation plus the params defined by any features in the +driver+
|
140
|
+
# that might modify this operation
|
141
|
+
def effective_params(driver)
|
142
|
+
driver.features(@collection.name).collect do |f|
|
143
|
+
f.decl.operation(@name)
|
144
|
+
end.flatten.select { |op| op }.inject(params.dup) do |result, fop|
|
145
|
+
fop.params.each_key do |k|
|
146
|
+
if result.has_key?(k)
|
147
|
+
raise DuplicateParamException, "Parameter '#{k}' for operation #{fop.name} in collection #{@collection.name}"
|
148
|
+
else
|
149
|
+
result[k] = fop.params[k]
|
150
|
+
end
|
151
|
+
end
|
152
|
+
result
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
99
156
|
private
|
100
157
|
def gen_route(name)
|
101
158
|
route_url = path
|
@@ -120,8 +177,11 @@ module Sinatra
|
|
120
177
|
@name = name
|
121
178
|
@description = ""
|
122
179
|
@operations = {}
|
180
|
+
@global = false
|
123
181
|
instance_eval(&block) if block_given?
|
124
182
|
generate_documentation
|
183
|
+
generate_head
|
184
|
+
generate_options
|
125
185
|
end
|
126
186
|
|
127
187
|
# Set/Return description for collection
|
@@ -132,10 +192,43 @@ module Sinatra
|
|
132
192
|
@description = text
|
133
193
|
end
|
134
194
|
|
195
|
+
# Mark this collection as global, i.e. independent of any specific
|
196
|
+
# driver
|
197
|
+
def global!
|
198
|
+
@global = true
|
199
|
+
end
|
200
|
+
|
201
|
+
# Return +true+ if this collection is global, i.e. independent of any
|
202
|
+
# specific driver
|
203
|
+
def global?
|
204
|
+
@global
|
205
|
+
end
|
206
|
+
|
207
|
+
def generate_head
|
208
|
+
current_collection = self
|
209
|
+
::Sinatra::Application.head("/api/#{name}") do
|
210
|
+
methods_allowed = current_collection.operations.collect { |o| o[1].method.to_s.upcase }.uniq.join(',')
|
211
|
+
headers 'Allow' => "HEAD,OPTIONS,#{methods_allowed}"
|
212
|
+
[200, '']
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def generate_options
|
217
|
+
current_collection = self
|
218
|
+
::Sinatra::Application.options("/api/#{name}") do
|
219
|
+
operations_allowed = current_collection.operations.collect { |o| o[0] }.join(',')
|
220
|
+
headers 'X-Operations-Allowed' => operations_allowed
|
221
|
+
[200, '']
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
135
225
|
def generate_documentation
|
136
|
-
coll
|
226
|
+
coll = self
|
137
227
|
::Sinatra::Application.get("/api/docs/#{@name}") do
|
138
|
-
|
228
|
+
coll.check_supported(driver)
|
229
|
+
@collection = coll
|
230
|
+
@operations = coll.operations
|
231
|
+
@features = driver.features(coll.name)
|
139
232
|
respond_to do |format|
|
140
233
|
format.html { haml :'docs/collection' }
|
141
234
|
format.xml { haml :'docs/collection' }
|
@@ -178,19 +271,10 @@ module Sinatra
|
|
178
271
|
end
|
179
272
|
end
|
180
273
|
|
181
|
-
def
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
fop.params.each_key do |k|
|
186
|
-
if cop.params.has_key?(k)
|
187
|
-
raise DuplicateParamException, "Parameter '#{k}' for operation #{fop.name} defined by collection #{@name} and by feature #{f.name}"
|
188
|
-
else
|
189
|
-
cop.params[k] = fop.params[k]
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
274
|
+
def check_supported(driver)
|
275
|
+
unless global? || driver.has_collection?(@name)
|
276
|
+
raise UnsupportedCollectionException,
|
277
|
+
"Collection #{@name} not supported by this driver"
|
194
278
|
end
|
195
279
|
end
|
196
280
|
end
|
@@ -206,9 +290,7 @@ module Sinatra
|
|
206
290
|
# operation on this collection.
|
207
291
|
def collection(name, &block)
|
208
292
|
raise DuplicateCollectionException if collections[name]
|
209
|
-
return unless Deltacloud::driver.has_collection?(name.to_sym)
|
210
293
|
collections[name] = Collection.new(name, &block)
|
211
|
-
collections[name].add_feature_params(Deltacloud::driver.features(name))
|
212
294
|
collections[name].generate
|
213
295
|
end
|
214
296
|
|
@@ -229,7 +311,9 @@ module Sinatra
|
|
229
311
|
end
|
230
312
|
|
231
313
|
def entry_points
|
232
|
-
collections.values.
|
314
|
+
collections.values.select { |coll|
|
315
|
+
coll.global? || driver.has_collection?(coll.name)
|
316
|
+
}.inject([]) do |m, coll|
|
233
317
|
url = url_for coll.operations[:index].path, :full
|
234
318
|
m << [ coll.name, url ]
|
235
319
|
end
|
@@ -240,37 +324,11 @@ module Sinatra
|
|
240
324
|
helpers RabbitHelper
|
241
325
|
end
|
242
326
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
end
|
249
|
-
|
250
|
-
# Title case.
|
251
|
-
#
|
252
|
-
# "this is a string".titlecase
|
253
|
-
# => "This Is A String"
|
254
|
-
#
|
255
|
-
# CREDIT: Eliazar Parra
|
256
|
-
# Copied from facets
|
257
|
-
def titlecase
|
258
|
-
gsub(/\b\w/){ $`[-1,1] == "'" ? $& : $&.upcase }
|
259
|
-
end
|
260
|
-
|
261
|
-
def pluralize
|
262
|
-
self + "s"
|
263
|
-
end
|
264
|
-
|
265
|
-
def singularize
|
266
|
-
self.gsub(/s$/, '')
|
267
|
-
end
|
268
|
-
|
269
|
-
def underscore
|
270
|
-
gsub(/::/, '/').
|
271
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
272
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
273
|
-
tr("-", "_").
|
274
|
-
downcase
|
327
|
+
configure do
|
328
|
+
class << Sinatra::Base
|
329
|
+
def options(path, opts={}, &block)
|
330
|
+
route 'OPTIONS', path, opts, &block
|
331
|
+
end
|
275
332
|
end
|
333
|
+
Sinatra::Delegator.delegate :options
|
276
334
|
end
|