---
server/lib/deltacloud/validation.rb | 38 ++++++++++--
server/lib/sinatra/rabbit.rb | 2 +
server/public/stylesheets/compiled/application.css | 7 ++
server/server.rb | 10 ++--
server/views/docs/operation.html.haml | 66 +++++++++++++++-----
5 files changed, 95 insertions(+), 28 deletions(-)
diff --git a/server/lib/deltacloud/validation.rb b/server/lib/deltacloud/validation.rb
index b4eb3ae..2ee040a 100644
--- a/server/lib/deltacloud/validation.rb
+++ b/server/lib/deltacloud/validation.rb
@@ -13,14 +13,30 @@ module Deltacloud::Validation
end
class Param
- attr_reader :name, :klass, :type, :options, :description
+ attr_reader :name, :klass, :type, :options, :validation, :description
def initialize(args)
@name = args[0]
@klass = args[1] || :string
@type = args[2] || :optional
- @options = args[3] || []
- @description = args[4] || ''
+
+ case args[3].class.name
+ when 'Hash':
+ @validation = args[3][:format]
+ when 'Array':
+ @options = args[3]
+ when 'String':
+ @description = args[3]
+ end
+
+ @description ||= args[4] || auto_docs(@name) || ''
+ end
+
+ def auto_docs(name)
+ case name.to_sym
+ when :id
+ "The id of the object to retrieve."
+ end
end
def required?
@@ -61,9 +77,19 @@ module Deltacloud::Validation
if p.required? and not values[p.name]
raise Failure.new(p, "Required parameter #{p.name} not found")
end
- if values[p.name] and not p.options.empty? and
- not p.options.include?(values[p.name])
- raise Failure.new(p, "Parameter #{p.name} has value #{values[p.name]} which
is not in #{p.options.join(", ")}")
+ if values[p.name] and not p.options.empty?
+ if p.options.class == Hash
+ if p.options[:format]
+ p.validation = p.options[:format]
+ if values[p.name].match(Regexp.new(p.options[:format])).nil?
+ raise Failure.new(p, "Parameter #{p.name} has invalid format
(#{p.options[:format].inspect})")
+ end
+ end
+ elsif p.options.class == Array
+ unless p.options.include?(values[p.name])
+ raise Failure.new(p, "Parameter #{p.name} has value #{values[p.name]}
which is not in #{p.options.join(',')}")
+ end
+ end
end
end
end
diff --git a/server/lib/sinatra/rabbit.rb b/server/lib/sinatra/rabbit.rb
index 6018810..a7dfa0f 100644
--- a/server/lib/sinatra/rabbit.rb
+++ b/server/lib/sinatra/rabbit.rb
@@ -48,6 +48,8 @@ module Sinatra
coll, oper = @collection, self
::Sinatra::Application.get("/api/docs/#{@collection.name}/#{@name}")
do
@collection, @operation = coll, oper
+ collection_features = driver.features((a)collection.name)
+ @features = collection_features.select { |f| f.operations.collect{ |o| o.name
}.include?(oper.name) }
respond_to do |format|
format.html { haml :'docs/operation' }
format.xml { haml :'docs/operation' }
diff --git a/server/public/stylesheets/compiled/application.css
b/server/public/stylesheets/compiled/application.css
index 969f712..a1f43c7 100644
--- a/server/public/stylesheets/compiled/application.css
+++ b/server/public/stylesheets/compiled/application.css
@@ -611,3 +611,10 @@ input[type='radio'] {
table.docs { border : 1px solid #ccc }
table.docs td { border : 1px solid #ccc }
table.docs table td { border : none }
+
+p { margin : 1em 0; }
+p.description { background : #eee; padding : 1em 0.5em; border : 1px dotted #ccc; }
+
+h2 { border-bottom : 1px solid #eee; }
+code { font-family : monospace; font-weight : bold; }
+td.type { color : red; font-weight : bold;}
diff --git a/server/server.rb b/server/server.rb
index b5bdfac..b262f81 100644
--- a/server/server.rb
+++ b/server/server.rb
@@ -226,9 +226,9 @@ collection :instances do
operation :create do
description "Create a new instance"
- param :image_id, :string, :required
- param :realm_id, :string, :optional
- param :hwp_id, :string, :optional
+ param :image_id, :string, :required, "The desired server image id"
+ param :realm_id, :string, :optional, "ID of realm you want to use for
instance"
+ param :hwp_id, :string, :optional, "ID of hardware profile to use"
control do
@image = driver.image(credentials, :id => params[:image_id])
instance = driver.create_instance(credentials, @image.id, params)
@@ -282,8 +282,8 @@ END
operation :index do
description "List of available hardware profiles"
- param :id, :string
- param :architecture, :string, :optional, [ 'i386', 'x86_64' ]
+ param :id, :string, :optional
+ param :architecture, :string, :optional, [ 'i386', 'x86_64' ],
"Show only profiles with given architecture"
control do
@profiles = driver.hardware_profiles(credentials, params)
respond_to do |format|
diff --git a/server/views/docs/operation.html.haml
b/server/views/docs/operation.html.haml
index ec6374b..8ec840a 100644
--- a/server/views/docs/operation.html.haml
+++ b/server/views/docs/operation.html.haml
@@ -1,31 +1,63 @@
+%h1 Documentation
+
%h2
- %a{:href => "/api/docs/#{(a)collection.name.to_s}"}
#{(a)collection.name.to_s.titlecase}
- #{'::'}
- #{(a)operation.name}
+ ="#{@collection.name}/#{(a)operation.name}"
+%p.description #{(a)operation.description}
+
+%h2 Request
-%p #{(a)operation.description}
+%h3 URL
+%p
+ ="#{url_for '/', :full}api/#{@collection.name}/#{@operation.name}"
-%br
-%h3
- URL:
- %u
- = "/api/#{@collection.name.to_s}/#{(a)operation.name.to_s}"
-%br
-%h3 Parameters:
+%h3 HTTP method
+%p
+ = @operation.method.to_s.upcase
+
+%h3 Input Request Query Parameters
%table
%thead
%tr
+ %th Required
%th Name
%th Type
- %th Class
- %th Valid values
+ %th Validation
+ %th{:style => 'width:25em'} Description
%tbody
- @operation.each_param do |p|
%tr
- %td{:style => "width:15em"}
- %em #{p.name}
- %td{:style => "width:10em"} #{p.type}
+ %td.type
+ =p.type if p.type.eql?(:required)
+ %td
+ %code #{p.name}
%td #{p.klass}
- %td{:style => "width:10em"} #{p.options.join(',')}
+ - if p.validation
+ %td #{p.validation.inspect if p.validation}
+ - elsif p.options
+ %td #{p.options.inspect}
+ - else
+ %td
+ %td #{p.description}
+ %tr
+ %td{:colspan => 5, :style => "background : #ccc"}
+ %strong Features:
+ - @features.each do |f|
+ - f.operations.collect { |o| [f, o.params ] }.each do |feature, feature_params|
+ %tr
+ %th{:colspan => 5} #{feature.name}
+ - feature_params.each do |name, p|
+ %tr
+ %td.type
+ =p.type if p.type.eql?(:required)
+ %td
+ %code #{name}
+ %td #{p.klass}
+ - if p.validation
+ %td #{p.validation.inspect if p.validation}
+ - elsif p.options
+ %td #{p.options.inspect}
+ - else
+ %td
+ %td #{p.description}
--
1.7.1