From: Michal Fojtik mfojtik@redhat.com
You now need the rest-client gem
See http://rdoc.info/projects/archiloque/rest-client --- client/lib/deltacloud.rb | 307 +++++++++++++++++++------------------------ client/specs/spec_helper.rb | 1 + 2 files changed, 134 insertions(+), 174 deletions(-)
diff --git a/client/lib/deltacloud.rb b/client/lib/deltacloud.rb index 5324c79..c38eb97 100644 --- a/client/lib/deltacloud.rb +++ b/client/lib/deltacloud.rb @@ -15,60 +15,78 @@ # 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 'uri' -require 'net/http' -require 'logger' +require 'rest_client' require 'rexml/document' - +require 'logger' require 'dcloud/flavor' require 'dcloud/realm' require 'dcloud/image' require 'dcloud/instance' require 'dcloud/storage_volume' require 'dcloud/storage_snapshot' - require 'dcloud/state' require 'dcloud/transition' +require 'base64' + +module RestClient + class Response + def body + self.to_s + end + end +end
class DeltaCloud
+ attr_accessor :logger + attr_reader :api_uri + attr_reader :entry_points + attr_reader :driver_name + def self.driver_name(url) DeltaCloud.new( nil, nil, url) do |client| return client.driver_name end end
- attr_accessor :logger - attr_reader :api_uri - attr_reader :entry_points - attr_reader :driver_name - def initialize(name, password, api_uri, &block) @logger = Logger.new( STDERR ) @name = name @password = password @api_uri = URI.parse( api_uri ) @entry_points = {} + discover_entry_points connect( &block ) self end
+ def connect(&block) - @http = Net::HTTP.new( api_host, api_port ) + @http = RestClient::Resource.new( api_uri.to_s , :accept => 'application/xml' ) discover_entry_points block.call( self ) if block self end
+ def api_host + @api_uri.host + end + + def api_port + @api_uri.port + end + + def api_path + @api_uri.path + end + def flavors(opts={}) flavors = [] - request( entry_points[:flavors], :get, opts ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - doc.get_elements( 'flavors/flavor' ).each do |flavor| - uri = flavor.attributes['href'] - flavors << DCloud::Flavor.new( self, uri, flavor ) - end + request(entry_points[:flavors], :get, opts) do |response| + doc = REXML::Document.new( response ) + doc.get_elements( 'flavors/flavor' ).each do |flavor| + uri = flavor.attributes['href'] + flavors << DCloud::Flavor.new( self, uri, flavor ) end end flavors @@ -76,15 +94,12 @@ class DeltaCloud
def flavor(id) request( entry_points[:flavors], :get, {:id=>id } ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - doc.get_elements( 'flavors/flavor' ).each do |flavor| - uri = flavor.attributes['href'] - return DCloud::Flavor.new( self, uri, flavor ) - end + doc = REXML::Document.new( response.body ) + doc.get_elements( '/flavor' ).each do |flavor| + uri = flavor.attributes['href'] + return DCloud::Flavor.new( self, uri, flavor ) end end - nil end
def fetch_flavor(uri) @@ -93,21 +108,29 @@ class DeltaCloud nil end
- def instance_states() + def fetch_resource(type, uri) + request( uri ) do |response| + doc = REXML::Document.new( response.body ) + if ( doc.root && ( doc.root.name == type.to_s.gsub( /_/, '-' ) ) ) + return doc.root + end + end + nil + end + + def instance_states states = [] request( entry_points[:instance_states] ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - doc.get_elements( 'states/state' ).each do |state_elem| - state = DCloud::State.new( state_elem.attributes['name'] ) - state_elem.get_elements( 'transition' ).each do |transition_elem| - state.transitions << DCloud::Transition.new( - transition_elem.attributes['to'], - transition_elem.attributes['action'] - ) - end - states << state + doc = REXML::Document.new( response.body ) + doc.get_elements( 'states/state' ).each do |state_elem| + state = DCloud::State.new( state_elem.attributes['name'] ) + state_elem.get_elements( 'transition' ).each do |transition_elem| + state.transitions << DCloud::Transition.new( + transition_elem.attributes['to'], + transition_elem.attributes['action'] + ) end + states << state end end states @@ -121,12 +144,10 @@ class DeltaCloud def realms(opts={}) realms = [] request( entry_points[:realms], :get, opts ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - doc.get_elements( 'realms/realm' ).each do |realm| - uri = realm.attributes['href'] - realms << DCloud::Realm.new( self, uri, realm ) - end + doc = REXML::Document.new( response.body ) + doc.get_elements( 'realms/realm' ).each do |realm| + uri = realm.attributes['href'] + realms << DCloud::Realm.new( self, uri, realm ) end end realms @@ -134,12 +155,10 @@ class DeltaCloud
def realm(id) request( entry_points[:realms], :get, {:id=>id } ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - doc.get_elements( 'realms/realm' ).each do |realm| - uri = realm.attributes['href'] - return DCloud::Realm.new( self, uri, realm ) - end + doc = REXML::Document.new( response.body ) + doc.get_elements( 'realm' ).each do |realm| + uri = realm.attributes['href'] + return DCloud::Realm.new( self, uri, realm ) end end nil @@ -155,12 +174,10 @@ class DeltaCloud images = [] request_path = entry_points[:images] request( request_path, :get, opts ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - doc.get_elements( 'images/image' ).each do |image| - uri = image.attributes['href'] - images << DCloud::Image.new( self, uri, image ) - end + doc = REXML::Document.new( response.body ) + doc.get_elements( 'images/image' ).each do |image| + uri = image.attributes['href'] + images << DCloud::Image.new( self, uri, image ) end end images @@ -168,32 +185,22 @@ class DeltaCloud
def image(id) request( entry_points[:images], :get, {:id=>id } ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - doc.get_elements( 'images/image' ).each do |instance| - uri = instance.attributes['href'] - return DCloud::Image.new( self, uri, instance ) - end + doc = REXML::Document.new( response.body ) + doc.get_elements( 'image' ).each do |instance| + uri = instance.attributes['href'] + return DCloud::Image.new( self, uri, instance ) end end nil end
- def fetch_image(uri) - xml = fetch_resource( :image, uri ) - return DCloud::Image.new( self, uri, xml ) if xml - nil - end - - def instances() + def instances instances = [] request( entry_points[:instances] ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - doc.get_elements( 'instances/instance' ).each do |instance| - uri = instance.attributes['href'] - instances << DCloud::Instance.new( self, uri, instance ) - end + doc = REXML::Document.new( response.body ) + doc.get_elements( 'instances/instance' ).each do |instance| + uri = instance.attributes['href'] + instances << DCloud::Instance.new( self, uri, instance ) end end instances @@ -201,12 +208,10 @@ class DeltaCloud
def instance(id) request( entry_points[:instances], :get, {:id=>id } ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - doc.get_elements( 'instances/instance' ).each do |instance| - uri = instance.attributes['href'] - return DCloud::Instance.new( self, uri, instance ) - end + doc = REXML::Document.new( response.body ) + doc.get_elements( 'instance' ).each do |instance| + uri = instance.attributes['href'] + return DCloud::Instance.new( self, uri, instance ) end end nil @@ -214,9 +219,7 @@ class DeltaCloud
def post_instance(uri) request( uri, :post ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - return true - end + return true end return false end @@ -239,24 +242,20 @@ class DeltaCloud
params[:image_id] = image_id request( entry_points[:instances], :post, {}, params ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - instance = doc.root - uri = instance.attributes['href'] - return DCloud::Instance.new( self, uri, instance ) - end + doc = REXML::Document.new( response.body ) + instance = doc.root + uri = instance.attributes['href'] + return DCloud::Instance.new( self, uri, instance ) end end
- def storage_volumes() + def storage_volumes storage_volumes = [] request( entry_points[:storage_volumes] ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - doc.get_elements( 'storage-volumes/storage-volume' ).each do |instance| - uri = instance.attributes['href'] - storage_volumes << DCloud::StorageVolume.new( self, uri, instance ) - end + doc = REXML::Document.new( response.body ) + doc.get_elements( 'storage-volumes/storage-volume' ).each do |instance| + uri = instance.attributes['href'] + storage_volumes << DCloud::StorageVolume.new( self, uri, instance ) end end storage_volumes @@ -264,12 +263,10 @@ class DeltaCloud
def storage_volume(id) request( entry_points[:storage_volumes], :get, {:id=>id } ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - doc.get_elements( 'storage-volumes/storage-volume' ).each do |storage_volume| - uri = storage_volume.attributes['href'] - return DCloud::StorageVolume.new( self, uri, storage_volume ) - end + doc = REXML::Document.new( response.body ) + doc.get_elements( 'storage-volume' ).each do |storage_volume| + uri = storage_volume.attributes['href'] + return DCloud::StorageVolume.new( self, uri, storage_volume ) end end nil @@ -284,12 +281,10 @@ class DeltaCloud def storage_snapshots() storage_snapshots = [] request( entry_points[:storage_snapshots] ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - doc.get_elements( 'storage-snapshots/storage-snapshot' ).each do |instance| - uri = instance.attributes['href'] - storage_snapshots << DCloud::StorageSnapshot.new( self, uri, instance ) - end + doc = REXML::Document.new( response.body ) + doc.get_elements( 'storage-snapshots/storage-snapshot' ).each do |instance| + uri = instance.attributes['href'] + storage_snapshots << DCloud::StorageSnapshot.new( self, uri, instance ) end end storage_snapshots @@ -297,12 +292,10 @@ class DeltaCloud
def storage_snapshot(id) request( entry_points[:storage_snapshots], :get, {:id=>id } ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - doc.get_elements( 'storage-snapshots/storage-snapshot' ).each do |storage_snapshot| - uri = storage_snapshot.attributes['href'] - return DCloud::StorageSnapshot.new( self, uri, storage_snapshot ) - end + doc = REXML::Document.new( response.body ) + doc.get_elements( 'storage-snapshot' ).each do |storage_snapshot| + uri = storage_snapshot.attributes['href'] + return DCloud::StorageSnapshot.new( self, uri, storage_snapshot ) end end nil @@ -314,61 +307,24 @@ class DeltaCloud nil end
- ## - ## - ## - ## - - def fetch_resource(type, uri) - request( uri ) do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - if ( doc.root && ( doc.root.name == type.to_s.gsub( /_/, '-' ) ) ) - return doc.root - end - end - end + def fetch_image(uri) + xml = fetch_resource( :image, uri ) + return DCloud::Image.new( self, uri, xml ) if xml nil end
- def api_host - @api_uri.host - end - - def api_port - @api_uri.port - end - - def api_path - @api_uri.path - end - private
attr_reader :http
- def build_hash(elem) - hash = {} - elem.elements.each do |element| - key = element.name.gsub( /-/, '_' ).to_sym - value = element.text || element.attributes['href'] - hash[key] = value - end - hash - end - - def discover_entry_points() - @entry_points = {} - logger << "Discoverying entry points at #{@api_uri}\n" - request do |response| - if ( response.is_a?( Net::HTTPSuccess ) ) - doc = REXML::Document.new( response.body ) - @driver_name = doc.root.attributes['driver'] - doc.get_elements( 'api/link' ).each do |link| - rel = link.attributes['rel'] - uri = link.attributes['href'] - @entry_points[rel.to_sym] = uri - end + def discover_entry_points + request(api_uri.to_s) do |response| + doc = REXML::Document.new( response.body ) + @driver_name = doc.root.attributes['driver'] + doc.get_elements( 'api/link' ).each do |link| + rel = link.attributes['rel'] + uri = link.attributes['href'] + @entry_points[rel.to_sym] = uri end end end @@ -377,21 +333,24 @@ class DeltaCloud if ( path =~ /^http/ ) request_path = path else - request_path = "#{api_path}#{path}" + request_path = "#{api_uri.to_s}#{path}" end - query_string = query_args.keys.collect{|key| "#{key}=#{query_args[key]}"}.join("&") - if ( query_string != '' ) - request_path += "?#{query_string}" + if query_args[:id] + request_path += "/#{query_args[:id]}" + query_args.delete(:id) end - - logger << "Request [#{method.to_s.upcase} #{request_path}]\n" - request = eval( "Net::HTTP::#{method.to_s.capitalize}" ).new( request_path ) - request.basic_auth( @name, @password ) - if ( method == :post ) - request.set_form_data( form_data ) + query_string = URI.escape(query_args.collect{|k,v| "#{k}=#{v}"}.join('&')) + request_path += "?#{query_string}" unless query_string=='' + headers = { + :authorization => "Basic "+Base64.encode64("#{@name}:#{@password}"), + :accept => "application/xml" + } + logger << "Request [#{method.to_s.upcase}] #{request_path}]\n" + if method.eql?(:get) + RestClient.send(method, request_path, headers, &block) + else + RestClient.send(method, request_path, form_data, headers, &block) end - request['Accept'] = 'text/xml' - http.request( request, &block ) end
end diff --git a/client/specs/spec_helper.rb b/client/specs/spec_helper.rb index 071b0bc..b9f9992 100644 --- a/client/specs/spec_helper.rb +++ b/client/specs/spec_helper.rb @@ -15,6 +15,7 @@ # 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 'yaml' require 'fileutils'