deltacloud-client 0.5.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/NOTICE CHANGED
@@ -1,5 +1,5 @@
1
1
  Apache Deltacloud
2
- Copyright 2010, 2011 The Apache Software Foundation
2
+ Copyright 2010-2012 The Apache Software Foundation
3
3
 
4
4
  This product includes software developed at The Apache Software Foundation
5
5
  (http://www.apache.org/).
data/Rakefile CHANGED
@@ -49,6 +49,13 @@ if available?('rspec')
49
49
  end
50
50
  end
51
51
 
52
+ desc "Reinstall gem"
53
+ task :reinstall do
54
+ puts %x{gem uninstall deltacloud-client --all -I -x}
55
+ puts %x{gem build deltacloud-client.gemspec}
56
+ puts %x{gem install deltacloud-client-*.gem --local}
57
+ end
58
+
52
59
  desc "Setup Fixtures"
53
60
  task 'fixtures' do
54
61
  FileUtils.rm_rf( File.dirname( __FILE__ ) + '/specs/data' )
data/bin/deltacloudc CHANGED
@@ -65,6 +65,8 @@ BANNER
65
65
  opts.on( '-n', '--name NAME', 'Name (for instance eg.)') { |name| options[:name] = name }
66
66
  opts.on( '-s', '--state STATE', 'Instance state (RUNNING, STOPPED)') { |state| options[:state] = state }
67
67
  opts.on( '-u', '--url URL', 'API url ($API_URL variable)') { |url| options[:api_url] = url }
68
+ opts.on( '-U', '--user USER', 'API username ($API_USERNAME variable)') { |u| options[:api_user] = u }
69
+ opts.on( '-P', '--password PASSWORD', 'API password ($API_PASSWORD variable)') { |p| options[:api_password] = p }
68
70
  opts.on( '-l', '--list', 'List collections/operations') { |id| options[:list] = true }
69
71
  opts.on( '-h', '--help', 'Display this screen' ) { puts @optparse; Kernel.exit! }
70
72
  opts.on( '-v', '--version', 'Display API version' ) { options[:version]=true }
@@ -104,7 +106,7 @@ options[:collection] = ARGV[0]
104
106
  options[:operation] = ARGV[1]
105
107
 
106
108
  # Connect to Deltacloud API and fetch all entry points
107
- client = DeltaCloud.new(url.user || ENV['API_USER'], url.password || ENV['API_PASSWORD'], api_url)
109
+ client = DeltaCloud.new(options[:api_user] || ENV['API_USER'], options[:api_password] || ENV['API_PASSWORD'], api_url)
108
110
  collections = client.entry_points.keys
109
111
 
110
112
  # Exclude collection which don't have methods in client library yet
data/lib/base_object.rb CHANGED
@@ -151,7 +151,7 @@ module DeltaCloud
151
151
  return providers.any? { |p| p.keys.include? args.first.to_sym }
152
152
  end
153
153
  if method_name == :"valid_provider_url?"
154
- return providers.map { |p| !p.find { |k, v| v.find { |u| u[:url] == args.first } }.nil? }
154
+ return providers.any? { |p| !p.find { |k, v| v.find { |u| u[:url] == args.first } }.nil? }
155
155
  end
156
156
  super
157
157
  else
data/lib/deltacloud.rb CHANGED
@@ -21,6 +21,7 @@ require 'hwp_properties'
21
21
  require 'instance_state'
22
22
  require 'documentation'
23
23
  require 'base_object'
24
+ require 'errors'
24
25
  require 'client_bucket_methods'
25
26
 
26
27
  module DeltaCloud
@@ -264,9 +265,13 @@ module DeltaCloud
264
265
  def discover_entry_points
265
266
  return if discovered?
266
267
  request(:get, @api_uri.to_s) do |response|
268
+ if response.code == 301
269
+ @api_uri = response.headers[:location]
270
+ return discover_entry_points
271
+ end
267
272
  api_xml = Nokogiri::XML(response)
268
- @driver_name = api_xml.xpath('/api').first['driver']
269
- @api_version = api_xml.xpath('/api').first['version']
273
+ @driver_name = api_xml.xpath('/api').first[:driver]
274
+ @api_version = api_xml.xpath('/api').first[:version]
270
275
 
271
276
  api_xml.css("api > link").each do |entry_point|
272
277
  rel, href = entry_point['rel'].to_sym, entry_point['href']
@@ -314,9 +319,7 @@ module DeltaCloud
314
319
 
315
320
  request(:post, entry_points[:"#{$1}s"], {}, params) do |response|
316
321
  obj = base_object(:"#{$1}", response)
317
- # All create calls must respond 201 HTTP code
318
- # to indicate that resource was created.
319
- handle_backend_error(response) if response.code!=201
322
+ response_error(response) unless response_successful?(response.code)
320
323
  yield obj if block_given?
321
324
  end
322
325
  return obj
@@ -349,6 +352,28 @@ module DeltaCloud
349
352
  headers
350
353
  end
351
354
 
355
+ def response_successful?(code)
356
+ return true if code.to_s =~ /^2(\d{2})$/
357
+ return true if code.to_s =~ /^3(\d{2})$/
358
+ return false
359
+ end
360
+
361
+ def response_error(response)
362
+ xml = Nokogiri::XML(response.to_s)
363
+ if (xml/'message').empty? and response.code.to_s =~ /4(\d{2})/
364
+ DeltaCloud::HTTPError.client_error(response.code)
365
+ else
366
+ opts = {
367
+ :driver => (xml/'backend').first[:driver],
368
+ :provider => (xml/'backend').first[:provider],
369
+ :params => (xml/'request/param').inject({}) { |r,p| r[:"#{p[:name]}"] = p.text; r }
370
+ }
371
+ backtrace = (xml/'backtrace').empty? ? nil : (xml/'backtrace').first.text.split("\n")[1..10].map { |l| l.strip }
372
+ DeltaCloud::HTTPError.server_error(xml.root[:status] || response.code,
373
+ (xml/'message').first.text, opts, backtrace)
374
+ end
375
+ end
376
+
352
377
  # Basic request method
353
378
  #
354
379
  def request(*args, &block)
@@ -367,55 +392,18 @@ module DeltaCloud
367
392
  if conf[:method].eql?(:post)
368
393
  resource = RestClient::Resource.new(conf[:path], :open_timeout => conf[:open_timeout], :timeout => conf[:timeout])
369
394
  resource.send(:post, conf[:form_data], default_headers.merge(extended_headers)) do |response, request, block|
370
- handle_backend_error(response) if [500, 502, 501, 401].include? response.code
371
- if response.respond_to?('body')
372
- yield response.body if block_given?
373
- else
374
- yield response.to_s if block_given?
375
- end
395
+ response_error(response) unless response_successful? response.code
396
+ yield response.to_s if block_given?
376
397
  end
377
398
  else
378
399
  resource = RestClient::Resource.new(conf[:path], :open_timeout => conf[:open_timeout], :timeout => conf[:timeout])
379
400
  resource.send(conf[:method], default_headers.merge(extended_headers)) do |response, request, block|
380
- handle_backend_error(response) if [500, 502, 501, 401].include? response.code
381
- if conf[:method].eql?(:get) and [301, 302, 307].include? response.code
382
- response.follow_redirection(request) do |response, request, block|
383
- if response.respond_to?('body')
384
- yield response.body if block_given?
385
- else
386
- yield response.to_s if block_given?
387
- end
388
- end
389
- else
390
- if response.respond_to?('body')
391
- yield response.body if block_given?
392
- else
393
- yield response.to_s if block_given?
394
- end
395
- end
401
+ response_error(response) unless response_successful? response.code
402
+ yield response.to_s if block_given?
396
403
  end
397
404
  end
398
405
  end
399
406
 
400
- # Re-raise backend errors as on exception in client with message from
401
- # backend
402
- class BackendError < StandardError
403
-
404
- def initialize(opts={})
405
- opts[:message] = "Not authorized / Invalid credentials" if opts[:code] == 401
406
- super("#{opts[:code]} : #{opts[:message]}")
407
- set_backtrace(opts[:backtrace].split("\n").map { |l| l.strip }[0..10]) if opts[:backtrace]
408
- end
409
-
410
- end
411
-
412
- def handle_backend_error(response)
413
- response_xml = Nokogiri::XML(response)
414
- backtrace = (response_xml/'error/backtrace').empty? ? nil : (response_xml/'error/backtrace').text
415
- raise BackendError.new(:message => (response_xml/'error/message').text,
416
- :code => response.code,
417
- :backtrace => backtrace)
418
- end
419
407
 
420
408
  # Check if specified collection have wanted feature
421
409
  def feature?(collection, name)
data/lib/errors.rb ADDED
@@ -0,0 +1,140 @@
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
+ module DeltaCloud
17
+ module HTTPError
18
+
19
+ class ClientError < StandardError
20
+
21
+ attr_reader :params, :driver, :provider
22
+
23
+ def initialize(code, message, opts={}, backtrace=nil)
24
+ @params, @driver, @provider = opts[:params], opts[:driver], opts[:provider]
25
+ if code.to_s =~ /^5(\d{2})/
26
+ message += "\nParameters: #{@params.inspect}\n"
27
+ message += "Driver: #{@driver}@#{@provider}"
28
+ end
29
+ super("#{code}\n\n#{self.class.superclass}: #{message}\n\n")
30
+ # If server provided us the backtrace, then replace client backtrace
31
+ # with the server one.
32
+ set_backtrace(backtrace) unless backtrace.nil?
33
+ end
34
+ end
35
+
36
+ class ServerError < ClientError; end
37
+ class UknownError < ClientError; end
38
+
39
+ # For sake of consistent documentation we need to create
40
+ # this exceptions manually, instead of using some meta-programming.
41
+ # Client will really appreciate this it will try to catch some
42
+ # specific exception.
43
+
44
+ # Client errors (4xx)
45
+ class BadRequest < ClientError; end
46
+ class Unauthorized < ClientError; end
47
+ class Forbidden < ClientError; end
48
+ class NotFound < ClientError; end
49
+ class MethodNotAllowed < ClientError; end
50
+ class NotAcceptable < ClientError; end
51
+ class RequestTimeout < ClientError; end
52
+ class Gone < ClientError; end
53
+ class ExpectationFailed < ClientError; end
54
+ class UnsupportedMediaType < ClientError; end
55
+
56
+ # Server errors (5xx)
57
+ class DeltacloudError < ServerError; end
58
+ class ProviderError < ServerError; end
59
+ class ProviderTimeout < ServerError; end
60
+ class ServiceUnavailable < ServerError; end
61
+ class NotImplemented < ServerError; end
62
+
63
+ class ExceptionHandler
64
+
65
+ attr_reader :http_status_code, :message, :trace
66
+
67
+ def initialize(status_code, message=nil, opts={}, backtrace=nil, &block)
68
+ @http_status_code = status_code.to_i
69
+ @trace = backtrace
70
+ @message = message || client_error_messages[status_code] || 'No error message received'
71
+ @options = opts
72
+ instance_eval(&block) if block_given?
73
+ end
74
+
75
+ def on(code, exception_class)
76
+ if code == @http_status_code
77
+ raise exception_class.new(code, @message, @options, @trace)
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ def client_error_messages
84
+ {
85
+ 400 => 'The request could not be understood by the server due to malformed syntax.',
86
+ 401 => 'Authentication required for this request or invalid credentials provided.',
87
+ 403 => 'Requested operation is not allowed for this resource.',
88
+ 404 => 'Not Found',
89
+ 405 => 'Method not allowed for this resource.',
90
+ 406 => 'Requested media type is not supported by server.',
91
+ 408 => 'The client did not produce a request within the time that the server was prepared to wait.',
92
+ 410 => 'The resource is no longer available'
93
+ }
94
+ end
95
+
96
+ end
97
+
98
+ def self.parse_response_error(response)
99
+
100
+ end
101
+
102
+ def self.client_error(code)
103
+ ExceptionHandler.new(code) do
104
+ # Client errors
105
+ on 400, BadRequest
106
+ on 401, Unauthorized
107
+ on 403, Forbidden
108
+ on 404, NotFound
109
+ on 405, MethodNotAllowed
110
+ on 406, NotAcceptable
111
+ on 408, RequestTimeout
112
+ on 410, Gone
113
+ end
114
+ end
115
+
116
+ def self.server_error(code, message, opts={}, backtrace=nil)
117
+ ExceptionHandler.new(code, message, opts, backtrace) do
118
+ # Client errors
119
+ on 400, BadRequest
120
+ on 401, Unauthorized
121
+ on 403, Forbidden
122
+ on 404, NotFound
123
+ on 405, MethodNotAllowed
124
+ on 406, NotAcceptable
125
+ on 408, RequestTimeout
126
+ on 410, Gone
127
+ on 415, UnsupportedMediaType
128
+ on 417, ExpectationFailed
129
+ # Server errors
130
+ on 500, DeltacloudError
131
+ on 501, NotImplemented
132
+ on 502, ProviderError
133
+ on 503, ServiceUnavailable
134
+ on 504, ProviderTimeout
135
+ end
136
+ raise Deltacloud::HTTPError::UnknownError.new(code, message, opts, backtrace)
137
+ end
138
+
139
+ end
140
+ end
@@ -23,6 +23,15 @@ module DeltaCloud
23
23
  end
24
24
  end
25
25
 
26
+ class Key < Base
27
+ def format
28
+ sprintf("%-10s | %-60s",
29
+ @obj.id[0,10],
30
+ @obj.fingerprint
31
+ )
32
+ end
33
+ end
34
+
26
35
  class Image < Base
27
36
  def format
28
37
  sprintf("%-10s | %-20s | %-6s | %-20s | %15s",
@@ -59,9 +68,9 @@ module DeltaCloud
59
68
  class Instance < Base
60
69
  def format
61
70
  sprintf("%-15s | %-15s | %-15s | %10s | %32s | %32s",
62
- @obj.id ? @obj.id[0,15] : '-',
63
- @obj.name ? @obj.name[0,15] : 'unknown',
64
- @obj.image.name ? @obj.image.name[0,15] : 'unknown',
71
+ @obj.id ? @obj.id.to_s[0,15] : '-',
72
+ @obj.name ? @obj.name.to_s[0,15] : 'unknown',
73
+ @obj.image.name ? @obj.image.name.to_s[0,15] : 'unknown',
65
74
  @obj.state ? @obj.state.to_s[0,10] : 'unknown',
66
75
  @obj.public_addresses.collect { |a| a[:address] }.join(',')[0,32],
67
76
  @obj.private_addresses.collect { |a| a[:address] }.join(',')[0,32]
@@ -96,6 +96,7 @@ describe "Blobs" do
96
96
  blob_list.size.should eql(bucket.size.to_i)
97
97
  blob_list.each do |b_id|
98
98
  blob = client.blob({"bucket" => bucket.name, :id => b_id})
99
+ puts blob.inspect
99
100
  blob.bucket.should_not be_nil
100
101
  blob.bucket.should be_a(String)
101
102
  blob.bucket.should eql(bucket.name)
@@ -31,7 +31,11 @@ describe "return JSON" do
31
31
 
32
32
  it 'should return JSON when using application/json, */*' do
33
33
  header_hash = {
34
- 'Accept' => "application/json, */*"
34
+ # FIXME: There is a bug in rack-accept that cause to respond with HTML
35
+ # to the configuration below.
36
+ #
37
+ # 'Accept' => "application/json, */*"
38
+ 'Accept' => "application/json"
35
39
  }
36
40
  client.get(header_hash) do |response, request, &block|
37
41
  response.code.should == 200
@@ -54,7 +58,7 @@ end
54
58
  describe "return HTML in different browsers" do
55
59
 
56
60
  it "wants XML using format parameter" do
57
- client['?format=xml'].get('Accept' => 'application/xhtml+xml') do |response, request, &block|
61
+ client.get(:params => { 'format' => 'xml' }, 'Accept' => 'application/xhtml+xml') do |response, request, &block|
58
62
  response.code.should == 200
59
63
  response.headers[:content_type].should =~ /^application\/xml/
60
64
  end
@@ -67,7 +71,7 @@ describe "return HTML in different browsers" do
67
71
  end
68
72
 
69
73
  it "wants HTML using format parameter and accept set to XML" do
70
- client['?format=html'].get('Accept' => 'application/xml') do |response, request, &block|
74
+ client.get(:params => { 'format' => 'html'}, 'Accept' => 'application/xml') do |response, request, &block|
71
75
  response.code.should == 200
72
76
  response.headers[:content_type].should =~ /^text\/html/
73
77
  end
@@ -0,0 +1,4 @@
1
+ :description: Fedora 10
2
+ :owner_id: fedoraproject
3
+ :architecture: x86_64
4
+ :id: img1
@@ -0,0 +1,4 @@
1
+ :description: Fedora 10
2
+ :owner_id: fedoraproject
3
+ :architecture: i386
4
+ :id: img2
@@ -0,0 +1,4 @@
1
+ :description: JBoss
2
+ :owner_id: mockuser
3
+ :architecture: i386
4
+ :id: img3
@@ -0,0 +1,16 @@
1
+ ---
2
+ :realm_id: us
3
+ :public_addresses:
4
+ - img1.inst0.public.com
5
+ :state: RUNNING
6
+ :name: "Mock Instance With Profile Change"
7
+ :private_addresses:
8
+ - img1.inst0.private.com
9
+ :image_id: img1
10
+ :instance_profile: !ruby/object:InstanceProfile
11
+ id: m1-large
12
+ memory: "12288"
13
+ :owner_id: mockuser
14
+ :actions:
15
+ - :reboot
16
+ - :stop
@@ -0,0 +1,9 @@
1
+ :name: MockUserInstance
2
+ :state: RUNNING
3
+ :image_id: img3
4
+ :owner_id: mockuser
5
+ :public_addresses: [ img3.inst1.public.com ]
6
+ :private_addresses: [ img3.inst1.private.com ]
7
+ :realm_id: us
8
+ :instance_profile: !ruby/object:InstanceProfile
9
+ id: m1-small
@@ -0,0 +1,9 @@
1
+ :name: AnotherInstance
2
+ :state: RUNNING
3
+ :image_id: img1
4
+ :owner_id: anotheruser
5
+ :public_addresses: [ img1.inst2.public.com ]
6
+ :private_addresses: [ img1.inst2.private.com ]
7
+ :realm_id: us
8
+ :instance_profile: !ruby/object:InstanceProfile
9
+ id: m1-large
@@ -0,0 +1,4 @@
1
+ :owner_id: fedoraproject
2
+ :created: Wed Jul 29 18:15:24 UTC 2009
3
+ :state: COMPLETED
4
+ :storage_volume_id: vol1
@@ -0,0 +1,4 @@
1
+ :owner_id: mockuser
2
+ :created: Wed Jul 29 18:15:24 UTC 2009
3
+ :state: COMPLETED
4
+ :storage_volume_id: vol2
@@ -0,0 +1,4 @@
1
+ :owner_id: mockuser
2
+ :created: Wed Jul 29 18:15:24 UTC 2009
3
+ :state: COMPLETED
4
+ :storage_volume_id: vol2
@@ -0,0 +1,7 @@
1
+ :owner_id: fedoraproject
2
+ :created: Thu Jul 30 14:35:11 UTC 2009
3
+ :state: AVAILABLE
4
+ :capacity: 1
5
+ :realm_id: us
6
+ :device:
7
+ :instance_id:
@@ -0,0 +1,7 @@
1
+ :owner_id: mockuser
2
+ :created: Thu Jul 30 14:35:11 UTC 2009
3
+ :state: AVAILABLE
4
+ :capacity: 1
5
+ :device:
6
+ :realm_id: us
7
+ :instance_id:
@@ -0,0 +1,7 @@
1
+ :owner_id: mockuser
2
+ :created: Thu Jul 30 14:35:11 UTC 2009
3
+ :state: IN-USE
4
+ :capacity: 1
5
+ :realm_id: us
6
+ :device: /dev/sda1
7
+ :instance_id: inst1
@@ -0,0 +1,59 @@
1
+ #
2
+ # Copyright (C) 2009-2011 Red Hat, Inc.
3
+ #
4
+ # Licensed to the Apache Software Foundation (ASF) under one or more
5
+ # contributor license agreements. See the NOTICE file distributed with
6
+ # this work for additional information regarding copyright ownership. The
7
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance with the
9
+ # License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
+ # License for the specific language governing permissions and limitations
17
+ # under the License.
18
+
19
+ require 'specs/spec_helper'
20
+
21
+ describe "server error handler" do
22
+
23
+ it_should_behave_like "all resources"
24
+
25
+ it 'should capture HTTP 500 error as DeltacloudError' do
26
+ DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
27
+ expect { client.realm('500') }.should raise_error(DeltaCloud::HTTPError::DeltacloudError)
28
+ end
29
+ end
30
+
31
+ it 'should capture HTTP 502 error as ProviderError' do
32
+ DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
33
+ expect { client.realm('502') }.should raise_error(DeltaCloud::HTTPError::ProviderError)
34
+ end
35
+ end
36
+
37
+ it 'should capture HTTP 501 error as NotImplemented' do
38
+ DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
39
+ expect { client.realm('501') }.should raise_error(DeltaCloud::HTTPError::NotImplemented)
40
+ end
41
+ end
42
+
43
+ it 'should capture HTTP 504 error as ProviderTimeout' do
44
+ DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
45
+ expect { client.realm('504') }.should raise_error(DeltaCloud::HTTPError::ProviderTimeout)
46
+ end
47
+ end
48
+
49
+ end
50
+
51
+ describe "client error handler" do
52
+
53
+ it 'should capture HTTP 404 error as NotFound' do
54
+ DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
55
+ expect { client.realm('non-existing-realm') }.should raise_error(DeltaCloud::HTTPError::NotFound)
56
+ end
57
+ end
58
+
59
+ end
@@ -62,18 +62,20 @@ describe "storage snapshot" do
62
62
 
63
63
  it "should return nil for unknown storage volume by ID" do
64
64
  client = DeltaCloud.new( API_NAME, API_PASSWORD, API_URL )
65
- client.connect do |client|
66
- storage_snapshot = client.storage_snapshot( "bogus" )
67
- storage_snapshot.should be_nil
68
- end
65
+ lambda {
66
+ client.connect do |client|
67
+ client.storage_snapshot( "bogus" )
68
+ end
69
+ }.should raise_error(DeltaCloud::HTTPError::NotFound)
69
70
  end
70
71
 
71
72
  it "should return nil for unknown storage volume by URI" do
72
73
  client = DeltaCloud.new( API_NAME, API_PASSWORD, API_URL )
73
- client.connect do |client|
74
- storage_snapshot = client.fetch_storage_snapshot( API_URL + '/storage_snapshots/bogus' )
75
- storage_snapshot.should be_nil
76
- end
74
+ lambda {
75
+ client.connect do |client|
76
+ client.fetch_storage_snapshot( API_URL + '/storage_snapshots/bogus' )
77
+ end
78
+ }.should raise_error(DeltaCloud::HTTPError::NotFound)
77
79
  end
78
80
 
79
81
  end
@@ -69,20 +69,22 @@ describe "storage volumes" do
69
69
  end
70
70
  end
71
71
 
72
- it "should return nil for unknown storage volume by ID" do
72
+ it "should raise exception for unknown storage volume by ID" do
73
73
  client = DeltaCloud.new( API_NAME, API_PASSWORD, API_URL )
74
- client.connect do |client|
75
- storage_volume = client.storage_volume( 'bogus' )
76
- storage_volume.should be_nil
77
- end
74
+ lambda {
75
+ client.connect do |client|
76
+ client.storage_volume( 'bogus' )
77
+ end
78
+ }.should raise_error(DeltaCloud::HTTPError::NotFound)
78
79
  end
79
80
 
80
- it "should return nil for unknown storage volume by URI" do
81
+ it "should raise exception for unknown storage volume by URI" do
81
82
  client = DeltaCloud.new( API_NAME, API_PASSWORD, API_URL )
82
- client.connect do |client|
83
- storage_volume = client.fetch_storage_volume( API_URL + '/storage_volumes/bogus' )
84
- storage_volume.should be_nil
85
- end
83
+ lambda {
84
+ client.connect do |client|
85
+ client.fetch_storage_volume( API_URL + '/storage_volumes/bogus' )
86
+ end
87
+ }.should raise_error(DeltaCloud::HTTPError::NotFound)
86
88
  end
87
89
 
88
90
 
metadata CHANGED
@@ -1,175 +1,169 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: deltacloud-client
3
- version: !ruby/object:Gem::Version
4
- hash: 11
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 5
9
- - 0
10
- version: 0.5.0
11
6
  platform: ruby
12
- authors:
13
- - Red Hat, Inc.
7
+ authors:
8
+ - The Apache Software Foundation
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-01-31 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-07-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: rest-client
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70208850754540 !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 13
29
- segments:
30
- - 1
31
- - 6
32
- - 1
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
33
21
  version: 1.6.1
34
22
  type: :runtime
35
- version_requirements: *id001
36
- - !ruby/object:Gem::Dependency
37
- name: nokogiri
38
23
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70208850754540
25
+ - !ruby/object:Gem::Dependency
26
+ name: nokogiri
27
+ requirement: &70208850754060 !ruby/object:Gem::Requirement
40
28
  none: false
41
- requirements:
42
- - - ">="
43
- - !ruby/object:Gem::Version
44
- hash: 1
45
- segments:
46
- - 1
47
- - 4
48
- - 3
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
49
32
  version: 1.4.3
50
33
  type: :runtime
51
- version_requirements: *id002
52
- - !ruby/object:Gem::Dependency
53
- name: rspec
54
34
  prerelease: false
55
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *70208850754060
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70208850753600 !ruby/object:Gem::Requirement
56
39
  none: false
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- hash: 15
61
- segments:
62
- - 2
63
- - 0
64
- - 0
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
65
43
  version: 2.0.0
66
44
  type: :development
67
- version_requirements: *id003
45
+ prerelease: false
46
+ version_requirements: *70208850753600
68
47
  description: Deltacloud REST Client for API
69
- email: deltacloud-users@lists.fedorahosted.org
70
- executables:
48
+ email: dev@deltacloud.apache.org
49
+ executables:
71
50
  - deltacloudc
72
51
  extensions: []
73
-
74
- extra_rdoc_files:
52
+ extra_rdoc_files:
75
53
  - LICENSE
76
54
  - NOTICE
77
- - DISCLAIMER
78
- files:
55
+ files:
79
56
  - Rakefile
80
- - lib/documentation.rb
81
- - lib/instance_state.rb
82
- - lib/deltacloud.rb
83
57
  - lib/base_object.rb
84
- - lib/string.rb
58
+ - lib/client_bucket_methods.rb
59
+ - lib/deltacloud.rb
60
+ - lib/documentation.rb
61
+ - lib/errors.rb
85
62
  - lib/hwp_properties.rb
63
+ - lib/instance_state.rb
86
64
  - lib/plain_formatter.rb
87
- - lib/client_bucket_methods.rb
65
+ - lib/string.rb
88
66
  - bin/deltacloudc
89
- - specs/keys_spec.rb
90
- - specs/images_spec.rb
91
- - specs/content_spec.rb
92
- - specs/initialization_spec.rb
67
+ - LICENSE
68
+ - NOTICE
93
69
  - specs/buckets_spec.rb
94
- - specs/fixtures/instances/inst2.yml
70
+ - specs/content_spec.rb
71
+ - specs/data/images/img1.yml
72
+ - specs/data/images/img2.yml
73
+ - specs/data/images/img3.yml
74
+ - specs/data/instances/inst0.yml
75
+ - specs/data/instances/inst1.yml
76
+ - specs/data/instances/inst2.yml
77
+ - specs/data/storage_snapshots/snap1.yml
78
+ - specs/data/storage_snapshots/snap2.yml
79
+ - specs/data/storage_snapshots/snap3.yml
80
+ - specs/data/storage_volumes/vol1.yml
81
+ - specs/data/storage_volumes/vol2.yml
82
+ - specs/data/storage_volumes/vol3.yml
83
+ - specs/errors_spec.rb
84
+ - specs/fixtures/images/img1.yml
85
+ - specs/fixtures/images/img2.yml
86
+ - specs/fixtures/images/img3.yml
95
87
  - specs/fixtures/instances/inst0.yml
96
88
  - specs/fixtures/instances/inst1.yml
97
- - specs/fixtures/storage_volumes/vol2.yml
98
- - specs/fixtures/storage_volumes/vol1.yml
99
- - specs/fixtures/storage_volumes/vol3.yml
89
+ - specs/fixtures/instances/inst2.yml
100
90
  - specs/fixtures/storage_snapshots/snap1.yml
101
- - specs/fixtures/storage_snapshots/snap3.yml
102
91
  - specs/fixtures/storage_snapshots/snap2.yml
103
- - specs/fixtures/images/img1.yml
104
- - specs/fixtures/images/img3.yml
105
- - specs/fixtures/images/img2.yml
106
- - specs/realms_spec.rb
107
- - specs/spec_helper.rb
108
- - specs/instances_spec.rb
109
- - specs/shared/resources.rb
92
+ - specs/fixtures/storage_snapshots/snap3.yml
93
+ - specs/fixtures/storage_volumes/vol1.yml
94
+ - specs/fixtures/storage_volumes/vol2.yml
95
+ - specs/fixtures/storage_volumes/vol3.yml
110
96
  - specs/hardware_profiles_spec.rb
97
+ - specs/images_spec.rb
98
+ - specs/initialization_spec.rb
111
99
  - specs/instance_states_spec.rb
112
- - specs/storage_volume_spec.rb
100
+ - specs/instances_spec.rb
101
+ - specs/keys_spec.rb
102
+ - specs/realms_spec.rb
103
+ - specs/shared/resources.rb
104
+ - specs/spec_helper.rb
113
105
  - specs/storage_snapshot_spec.rb
114
- - LICENSE
115
- - NOTICE
116
- - DISCLAIMER
106
+ - specs/storage_volume_spec.rb
117
107
  homepage: http://www.deltacloud.org
118
108
  licenses: []
119
-
120
109
  post_install_message:
121
110
  rdoc_options: []
122
-
123
- require_paths:
111
+ require_paths:
124
112
  - lib
125
- required_ruby_version: !ruby/object:Gem::Requirement
113
+ required_ruby_version: !ruby/object:Gem::Requirement
126
114
  none: false
127
- requirements:
128
- - - ">="
129
- - !ruby/object:Gem::Version
130
- hash: 3
131
- segments:
132
- - 0
133
- version: "0"
134
- required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
120
  none: false
136
- requirements:
137
- - - ">="
138
- - !ruby/object:Gem::Version
139
- hash: 3
140
- segments:
141
- - 0
142
- version: "0"
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
143
125
  requirements: []
144
-
145
126
  rubyforge_project:
146
- rubygems_version: 1.8.11
127
+ rubygems_version: 1.8.15
147
128
  signing_key:
148
129
  specification_version: 3
149
130
  summary: Deltacloud REST Client
150
- test_files:
151
- - specs/keys_spec.rb
152
- - specs/images_spec.rb
153
- - specs/content_spec.rb
154
- - specs/initialization_spec.rb
131
+ test_files:
155
132
  - specs/buckets_spec.rb
156
- - specs/fixtures/instances/inst2.yml
133
+ - specs/content_spec.rb
134
+ - specs/data/images/img1.yml
135
+ - specs/data/images/img2.yml
136
+ - specs/data/images/img3.yml
137
+ - specs/data/instances/inst0.yml
138
+ - specs/data/instances/inst1.yml
139
+ - specs/data/instances/inst2.yml
140
+ - specs/data/storage_snapshots/snap1.yml
141
+ - specs/data/storage_snapshots/snap2.yml
142
+ - specs/data/storage_snapshots/snap3.yml
143
+ - specs/data/storage_volumes/vol1.yml
144
+ - specs/data/storage_volumes/vol2.yml
145
+ - specs/data/storage_volumes/vol3.yml
146
+ - specs/errors_spec.rb
147
+ - specs/fixtures/images/img1.yml
148
+ - specs/fixtures/images/img2.yml
149
+ - specs/fixtures/images/img3.yml
157
150
  - specs/fixtures/instances/inst0.yml
158
151
  - specs/fixtures/instances/inst1.yml
159
- - specs/fixtures/storage_volumes/vol2.yml
160
- - specs/fixtures/storage_volumes/vol1.yml
161
- - specs/fixtures/storage_volumes/vol3.yml
152
+ - specs/fixtures/instances/inst2.yml
162
153
  - specs/fixtures/storage_snapshots/snap1.yml
163
- - specs/fixtures/storage_snapshots/snap3.yml
164
154
  - specs/fixtures/storage_snapshots/snap2.yml
165
- - specs/fixtures/images/img1.yml
166
- - specs/fixtures/images/img3.yml
167
- - specs/fixtures/images/img2.yml
168
- - specs/realms_spec.rb
169
- - specs/spec_helper.rb
170
- - specs/instances_spec.rb
171
- - specs/shared/resources.rb
155
+ - specs/fixtures/storage_snapshots/snap3.yml
156
+ - specs/fixtures/storage_volumes/vol1.yml
157
+ - specs/fixtures/storage_volumes/vol2.yml
158
+ - specs/fixtures/storage_volumes/vol3.yml
172
159
  - specs/hardware_profiles_spec.rb
160
+ - specs/images_spec.rb
161
+ - specs/initialization_spec.rb
173
162
  - specs/instance_states_spec.rb
174
- - specs/storage_volume_spec.rb
163
+ - specs/instances_spec.rb
164
+ - specs/keys_spec.rb
165
+ - specs/realms_spec.rb
166
+ - specs/shared/resources.rb
167
+ - specs/spec_helper.rb
175
168
  - specs/storage_snapshot_spec.rb
169
+ - specs/storage_volume_spec.rb
data/DISCLAIMER DELETED
@@ -1,8 +0,0 @@
1
- Apache Deltacloud is an effort undergoing incubation at The Apache Software
2
- Foundation (ASF), sponsored by the Incubator PMC. Incubation is required of
3
- all newly accepted projects until a further review indicates that the
4
- infrastructure, communications, and decision making process have stabilized
5
- in a manner consistent with other successful ASF projects. While
6
- incubation status is not necessarily a reflection of the completeness or
7
- stability of the code, it does indicate that the project has yet to be
8
- fully endorsed by the ASF.