You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltacloud.apache.org by lu...@apache.org on 2010/07/09 01:36:51 UTC

svn commit: r962209 - in /incubator/deltacloud/trunk: client/bin/ client/lib/ server/libexec/lib/sinatra/ server/libexec/views/docs/

Author: lutter
Date: Thu Jul  8 23:36:51 2010
New Revision: 962209

URL: http://svn.apache.org/viewvc?rev=962209&view=rev
Log:
Added documentation and command line client

Added:
    incubator/deltacloud/trunk/client/bin/
    incubator/deltacloud/trunk/client/bin/deltacloudc   (with props)
    incubator/deltacloud/trunk/server/libexec/views/docs/collection.xml.haml
    incubator/deltacloud/trunk/server/libexec/views/docs/index.xml.haml
    incubator/deltacloud/trunk/server/libexec/views/docs/operation.xml.haml
Modified:
    incubator/deltacloud/trunk/client/lib/deltacloud.rb
    incubator/deltacloud/trunk/server/libexec/lib/sinatra/rabbit.rb

Added: incubator/deltacloud/trunk/client/bin/deltacloudc
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/client/bin/deltacloudc?rev=962209&view=auto
==============================================================================
--- incubator/deltacloud/trunk/client/bin/deltacloudc (added)
+++ incubator/deltacloud/trunk/client/bin/deltacloudc Thu Jul  8 23:36:51 2010
@@ -0,0 +1,147 @@
+#!/bin/env ruby
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+require 'rubygems'
+require 'optparse'
+require 'uri'
+require 'deltacloud'
+
+options = {}
+
+@optparse = OptionParser.new do |opts|
+
+opts.banner = <<BANNER
+Usage:
+deltacloudc collection operation [options]
+
+URL format:
+API_URL=http://[user]:[password]@[api_url][port][/uri]
+
+Options:
+BANNER
+  opts.on( '-i', '--id ID', 'ID for operation') { |id| options[:id] = id }
+  opts.on( nil, '--image-id ID', 'Image ID') { |id| options[:image_id] = id }
+  opts.on( nil, '--arch ARCH', 'Architecture (x86, x86_64)') { |id| options[:architecture] = id }
+  opts.on( nil, '--flavor_id FLAVOR', 'Flavor') { |id| options[:flavor_id] = id }
+  opts.on( nil, '--name NAME', 'Name (for instance eg.)') { |name| options[:name] = name }
+  opts.on( '-u', '--url URL', 'API url ($API_URL variable)') { |url| options[:api_url] = url }
+  opts.on( '-l', '--list', 'List collections/operations') { |id| options[:list] = true }
+  opts.on( '-h', '--help', 'Display this screen' ) { puts opts ; exit }
+  opts.on( '-v', '--version', 'Display API version' ) { options[:version]=true }
+end
+
+def invalid_usage(error_msg='')
+  puts "ERROR: #{error_msg}"
+  exit(1)
+end
+
+@optparse.parse!
+
+# First try to get API_URL from environment
+options[:api_url] = ENV['API_URL'] if options[:api_url].nil?
+
+url = URI.parse(options[:api_url])
+api_url = "http://#{url.host}#{url.port ? ":#{url.port}" : ''}#{url.path}"
+
+options[:collection] = ARGV[0]
+options[:operation] = ARGV[1]
+
+# Connect to Deltacloud API and fetch all entry points
+client = DeltaCloud.new(url.user, url.password, api_url)
+collections = client.entry_points.keys
+
+# Exclude collection which don't have methods in client library yet
+collections.delete(:hardware_profiles)
+collections.delete(:instance_states)
+
+# If list parameter passed print out available collection
+# with API documentation
+if options[:list] and options[:collection].nil?
+  collections.each do |c|
+    doc = client.fetch_documentation(c.to_s)
+    puts sprintf("%-22s: %s", c.to_s[0, 22], doc[:description])
+  end
+  exit(0)
+end
+
+# If collection parameter is present and user requested list
+# print all operation defined for collection with API documentation
+if options[:list] and options[:collection]
+  doc = client.fetch_documentation(options[:collection])
+  doc[:operations].each do |c|
+    puts sprintf("%-20s: %s", c[:name][0, 20], c[:description])
+  end
+  exit(0)
+end
+
+if options[:version]
+  puts "Deltacloud API(#{client.driver_name}) 0.1"
+  exit(0)
+end
+
+# List items from collection (typically /flavors)
+# Do same if 'index' operation is set
+if options[:collection] and ( options[:operation].nil? or options[:operation].eql?('index') )
+  invalid_usage("Unknown collection: #{options[:collection]}") unless collections.include?(options[:collection].to_sym)
+  params = {}
+  params.merge!(:architecture => options[:architecture]) if options[:architecture]
+  params.merge!(:id => options[:id]) if options[:id]
+  client.send(options[:collection].to_s, params).each do |model|
+    puts model.to_plain
+  end
+  exit(0)
+end
+
+if options[:collection] and options[:operation]
+
+  invalid_usage("Unknown collection: #{options[:collection]}") unless collections.include?(options[:collection].to_sym)
+
+  params = {}
+  params.merge!(:id => options[:id]) if options[:id]
+
+  # If collection is set and requested operation is 'show' just 'singularize'
+  # collection name and print item with specified id (-i parameter)
+  if options[:operation].eql?('show')
+    puts client.send(options[:collection].gsub(/s$/, ''), options[:id] ).to_plain
+    exit(0)
+  end
+
+  # If collection is set and requested operation is create new instance,
+  # --image-id, --flavor-id and --name parameters are used
+  # Returns created instance in plain form
+  if options[:collection].eql?('instances') and options[:operation].eql?('create')
+    params.merge!(:name => options[:name]) if options[:name]
+    params.merge!(:image_id => options[:image_id]) if options[:image_id]
+    params.merge!(:flavor_id => options[:flavor_id]) if options[:flavor_id]
+    instance = client.create_instance(options[:image_id], params)
+    puts instance.to_plain
+    exit(0)
+  end
+
+  # All other operations above collections is done there:
+  if options[:collection].eql?('instances')
+    instance = client.instance(options[:id])
+    instance.send("#{options[:operation]}!".to_s)
+    instance = client.instance(options[:id])
+    puts instance.to_plain
+    exit(0)
+  end
+end
+
+# If all above passed (eg. no parameters)
+puts @optparse

Propchange: incubator/deltacloud/trunk/client/bin/deltacloudc
------------------------------------------------------------------------------
    svn:executable = *

Modified: incubator/deltacloud/trunk/client/lib/deltacloud.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/client/lib/deltacloud.rb?rev=962209&r1=962208&r2=962209&view=diff
==============================================================================
--- incubator/deltacloud/trunk/client/lib/deltacloud.rb (original)
+++ incubator/deltacloud/trunk/client/lib/deltacloud.rb Thu Jul  8 23:36:51 2010
@@ -118,6 +118,38 @@ class DeltaCloud
     nil
   end
 
+  def fetch_documentation(collection, operation=nil)
+    response = @http["docs/#{collection}#{operation ? "/#{operation}" : ''}"].get(:accept => "application/xml")
+    doc = REXML::Document.new( response )
+    if operation.nil?
+      docs = {
+        :name => doc.get_elements('docs/collection').first.attributes['name'],
+        :description => doc.get_elements('docs/collection/description').first.text,
+        :operations => []
+      }
+      doc.get_elements('docs/collection/operations/operation').each do |operation|
+        p = {}
+        p[:name] = operation.attributes['name']
+        p[:description] = operation.get_elements('description').first.text
+        p[:parameters] = []
+        operation.get_elements('parameter').each do |param|
+          p[:parameters] << param.attributes['name']
+        end
+        docs[:operations] << p
+      end
+    else
+      docs = {
+        :name => doc.get_elements('docs/operation').attributes['name'],
+        :description => doc.get_elements('docs/operation/description').first.text,
+        :parameters => []
+      }
+      doc.get_elements('docs/operation/parameter').each do |param|
+        docs[:parameters] << param.attributes['name']
+      end
+    end
+    docs
+  end
+
   def instance_states
     states = []
     request( entry_points[:instance_states] ) do |response|
@@ -194,7 +226,7 @@ class DeltaCloud
     nil
   end
 
-  def instances
+  def instances(id=nil)
     instances = []
     request( entry_points[:instances] ) do |response|
       doc = REXML::Document.new( response.body )
@@ -249,7 +281,7 @@ class DeltaCloud
     end
   end
 
-  def storage_volumes
+  def storage_volumes(id=nil)
     storage_volumes = []
     request( entry_points[:storage_volumes] ) do |response|
       doc = REXML::Document.new( response.body )
@@ -278,7 +310,7 @@ class DeltaCloud
     nil
   end
 
-  def storage_snapshots()
+  def storage_snapshots(id=nil)
     storage_snapshots = []
     request( entry_points[:storage_snapshots] ) do |response|
       doc = REXML::Document.new( response.body )
@@ -345,7 +377,7 @@ class DeltaCloud
       :authorization => "Basic "+Base64.encode64("#{@name}:#{@password}"),
       :accept => "application/xml"
     }
-    logger << "Request [#{method.to_s.upcase}] #{request_path}]\n"
+    # logger << "Request [#{method.to_s.upcase}] #{request_path}]\n"
     if method.eql?(:get)
       RestClient.send(method, request_path, headers, &block)
     else

Modified: incubator/deltacloud/trunk/server/libexec/lib/sinatra/rabbit.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/libexec/lib/sinatra/rabbit.rb?rev=962209&r1=962208&r2=962209&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/libexec/lib/sinatra/rabbit.rb (original)
+++ incubator/deltacloud/trunk/server/libexec/lib/sinatra/rabbit.rb Thu Jul  8 23:36:51 2010
@@ -49,6 +49,7 @@ module Sinatra
           @collection, @operation = coll, oper
           respond_to do |format|
             format.html { haml :'docs/operation' }
+            format.xml { haml :'docs/operation' }
           end
         end
       end
@@ -146,6 +147,7 @@ module Sinatra
           @collection, @operations = coll, oper
           respond_to do |format|
             format.html { haml :'docs/collection' }
+            format.xml { haml :'docs/collection' }
           end
         end
       end
@@ -205,6 +207,7 @@ module Sinatra
     get '/api/docs\/?' do
       respond_to do |format|
         format.html { haml :'docs/index' }
+        format.xml { haml :'docs/index' }
       end
     end
 

Added: incubator/deltacloud/trunk/server/libexec/views/docs/collection.xml.haml
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/libexec/views/docs/collection.xml.haml?rev=962209&view=auto
==============================================================================
--- incubator/deltacloud/trunk/server/libexec/views/docs/collection.xml.haml (added)
+++ incubator/deltacloud/trunk/server/libexec/views/docs/collection.xml.haml Thu Jul  8 23:36:51 2010
@@ -0,0 +1,14 @@
+%docs{:status => "unsupported"}
+  %collection{:url => "/api/docs/#{@collection.name}", :name => "#{@collection.name}"}
+    %description #{@collection.description}
+    %operations
+      - @operations.keys.sort_by { |k| k.to_s }.each do |operation|
+        %operation{:url => "/api/#{@collection.name.to_s}", :name => "#{operation}", :href => "#{@operations[operation].path}", :method => "#{@operations[operation].method}"}
+          %description #{@operations[operation].description}
+          - @operations[operation].params.each_key do |p|
+            %parameter{:name => "#{p}", :type => "#{@operations[operation].params[p][:type]}"}
+              %class #{@operations[operation].params[p][:class]}
+              - unless @operations[operation].params[p][:options].empty?
+                %values
+                  - @operations[operation].params[p][:options].each do |v|
+                    %value #{v}

Added: incubator/deltacloud/trunk/server/libexec/views/docs/index.xml.haml
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/libexec/views/docs/index.xml.haml?rev=962209&view=auto
==============================================================================
--- incubator/deltacloud/trunk/server/libexec/views/docs/index.xml.haml (added)
+++ incubator/deltacloud/trunk/server/libexec/views/docs/index.xml.haml Thu Jul  8 23:36:51 2010
@@ -0,0 +1,5 @@
+%docs{:status => "unsupported"}
+  - collections.keys.sort_by { |k| k.to_s }.each do |collection|
+    %collection{:url => "/api/docs/#{collection}"}
+      %name #{collection}
+      %description  #{collections[collection].description}

Added: incubator/deltacloud/trunk/server/libexec/views/docs/operation.xml.haml
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/libexec/views/docs/operation.xml.haml?rev=962209&view=auto
==============================================================================
--- incubator/deltacloud/trunk/server/libexec/views/docs/operation.xml.haml (added)
+++ incubator/deltacloud/trunk/server/libexec/views/docs/operation.xml.haml Thu Jul  8 23:36:51 2010
@@ -0,0 +1,10 @@
+%docs{:status => "unsupported"}
+  %operation{:url => "/api/docs/#{@collection.name.to_s}", :name => "#{@operation.name.to_s}", :href => "#{@operation.path}", :method => "#{@operation.method}"}
+    %description #{@operation.description}
+    - @operation.params.each_key do |p|
+      %parameter{:name => "#{p}", :type => "#{@operation.params[p][:type]}"}
+        %class #{@operation.params[p][:class]}
+        - unless @operation.params[p][:options].empty?
+          %values
+            - @operation.params[p][:options].each do |v|
+              %value #{v}