deltacloud-client 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +73 -0
- data/Rakefile +88 -5
- data/lib/deltacloud/client.rb +79 -0
- data/lib/deltacloud/client/base_error.rb +80 -0
- data/lib/deltacloud/client/connection.rb +139 -0
- data/lib/deltacloud/client/helpers/model_helper.rb +69 -0
- data/lib/deltacloud/client/helpers/property_helper.rb +103 -0
- data/lib/deltacloud/client/helpers/xml_helper.rb +33 -0
- data/lib/deltacloud/client/methods.rb +33 -0
- data/lib/deltacloud/client/methods/address.rb +67 -0
- data/lib/deltacloud/client/methods/api.rb +96 -0
- data/lib/deltacloud/client/methods/backward_compatiblity.rb +72 -0
- data/lib/deltacloud/client/methods/blob.rb +91 -0
- data/lib/deltacloud/client/methods/bucket.rb +55 -0
- data/lib/deltacloud/client/methods/common.rb +46 -0
- data/lib/deltacloud/client/methods/driver.rb +53 -0
- data/lib/deltacloud/client/methods/firewall.rb +67 -0
- data/lib/deltacloud/client/methods/hardware_profile.rb +41 -0
- data/lib/deltacloud/client/methods/image.rb +61 -0
- data/lib/deltacloud/client/methods/instance.rb +141 -0
- data/lib/deltacloud/client/methods/instance_state.rb +41 -0
- data/lib/deltacloud/client/methods/key.rb +58 -0
- data/lib/deltacloud/client/methods/load_balancer.rb +96 -0
- data/lib/deltacloud/client/methods/metric.rb +54 -0
- data/lib/deltacloud/client/methods/realm.rb +42 -0
- data/lib/deltacloud/client/methods/storage_snapshot.rb +61 -0
- data/lib/deltacloud/client/methods/storage_volume.rb +94 -0
- data/lib/deltacloud/client/models.rb +32 -0
- data/lib/deltacloud/client/models/address.rb +57 -0
- data/lib/deltacloud/client/models/base.rb +153 -0
- data/lib/deltacloud/client/models/blob.rb +56 -0
- data/lib/deltacloud/client/models/bucket.rb +65 -0
- data/lib/deltacloud/client/models/driver.rb +87 -0
- data/lib/deltacloud/client/models/firewall.rb +64 -0
- data/lib/deltacloud/client/models/hardware_profile.rb +68 -0
- data/lib/deltacloud/client/models/image.rb +60 -0
- data/lib/deltacloud/client/models/instance.rb +142 -0
- data/lib/deltacloud/client/models/instance_address.rb +40 -0
- data/lib/{instance_state.rb → deltacloud/client/models/instance_state.rb} +11 -3
- data/lib/deltacloud/client/models/key.rb +52 -0
- data/lib/deltacloud/client/models/load_balancer.rb +55 -0
- data/lib/deltacloud/client/models/metric.rb +72 -0
- data/lib/deltacloud/client/models/realm.rb +29 -0
- data/lib/deltacloud/client/models/storage_snapshot.rb +54 -0
- data/lib/deltacloud/client/models/storage_volume.rb +96 -0
- data/lib/deltacloud/core_ext.rb +19 -0
- data/lib/deltacloud/core_ext/element.rb +32 -0
- data/lib/deltacloud/core_ext/fixnum.rb +30 -0
- data/lib/deltacloud/core_ext/nil.rb +22 -0
- data/lib/{string.rb → deltacloud/core_ext/string.rb} +16 -26
- data/lib/deltacloud/error_response.rb +93 -0
- data/tests/client/client_test.rb +51 -0
- data/tests/client/connection_test.rb +77 -0
- data/tests/core_ext/element_test.rb +40 -0
- data/tests/core_ext/fixnum_test.rb +35 -0
- data/tests/core_ext/nil.rb +27 -0
- data/tests/core_ext/string_test.rb +47 -0
- data/tests/fixtures/instances_cleanup.yml +681 -0
- data/tests/fixtures/test_0001_connects_to_Deltacloud_API.yml +60 -0
- data/tests/fixtures/test_0001_support_cpu.yml +444 -0
- data/tests/fixtures/test_0001_support_original_body.yml +116 -0
- data/tests/fixtures/test_0001_supports_addresses.yml +178 -0
- data/tests/fixtures/test_0001_supports_api_host.yml +60 -0
- data/tests/fixtures/test_0001_supports_attached_.yml +282 -0
- data/tests/fixtures/test_0001_supports_blobs.yml +475 -0
- data/tests/fixtures/test_0001_supports_bucket.yml +200 -0
- data/tests/fixtures/test_0001_supports_buckets.yml +160 -0
- data/tests/fixtures/test_0001_supports_drivers.yml +202 -0
- data/tests/fixtures/test_0001_supports_firewalls.yml +399 -0
- data/tests/fixtures/test_0001_supports_hardware_profiles.yml +262 -0
- data/tests/fixtures/test_0001_supports_images.yml +224 -0
- data/tests/fixtures/test_0001_supports_instance_states.yml +156 -0
- data/tests/fixtures/test_0001_supports_instances.yml +486 -0
- data/tests/fixtures/test_0001_supports_keys.yml +198 -0
- data/tests/fixtures/test_0001_supports_path.yml +60 -0
- data/tests/fixtures/test_0001_supports_realms.yml +152 -0
- data/tests/fixtures/test_0001_supports_storage_snapshots.yml +164 -0
- data/tests/fixtures/test_0001_supports_storage_volumes.yml +176 -0
- data/tests/fixtures/test_0001_supports_to_get_providers.yml +410 -0
- data/tests/fixtures/test_0002_support_blob.yml +148 -0
- data/tests/fixtures/test_0002_support_instance_state.yml +204 -0
- data/tests/fixtures/test_0002_support_memory.yml +444 -0
- data/tests/fixtures/test_0002_support_on_Provider.yml +130 -0
- data/tests/fixtures/test_0002_supports_api_port.yml +60 -0
- data/tests/fixtures/test_0002_supports_api_uri.yml +60 -0
- data/tests/fixtures/test_0002_supports_driver.yml +219 -0
- data/tests/fixtures/test_0002_supports_extract_xml_body_using_faraday_connection.yml +117 -0
- data/tests/fixtures/test_0002_supports_filtering_addresses_by_id_param.yml +156 -0
- data/tests/fixtures/test_0002_supports_filtering_buckets_by_id_param.yml +156 -0
- data/tests/fixtures/test_0002_supports_filtering_firewalls_by_id_param.yml +207 -0
- data/tests/fixtures/test_0002_supports_filtering_hardware_profiles_by_id_param.yml +158 -0
- data/tests/fixtures/test_0002_supports_filtering_images_by_id_param.yml +165 -0
- data/tests/fixtures/test_0002_supports_filtering_instances_by_id_param.yml +164 -0
- data/tests/fixtures/test_0002_supports_filtering_keys_by_id_param.yml +178 -0
- data/tests/fixtures/test_0002_supports_filtering_realms_by_id.yml +104 -0
- data/tests/fixtures/test_0002_supports_filtering_storage_snapshots_by_id_param.yml +155 -0
- data/tests/fixtures/test_0002_supports_filtering_storage_volumes_by_id_param.yml +157 -0
- data/tests/fixtures/test_0002_supports_hardware_profiles.yml +262 -0
- data/tests/fixtures/test_0002_supports_is_compatible_.yml +116 -0
- data/tests/fixtures/test_0002_supports_snapshot_.yml +202 -0
- data/tests/fixtures/test_0002_supports_version.yml +60 -0
- data/tests/fixtures/test_0003_caches_the_API_entrypoint.yml +60 -0
- data/tests/fixtures/test_0003_support_address.yml +197 -0
- data/tests/fixtures/test_0003_support_bucket.yml +198 -0
- data/tests/fixtures/test_0003_support_create_blob.yml +105 -0
- data/tests/fixtures/test_0003_support_create_blob_and_destroy_blob.yml +138 -0
- data/tests/fixtures/test_0003_support_firewall.yml +768 -0
- data/tests/fixtures/test_0003_support_hardware_profile.yml +199 -0
- data/tests/fixtures/test_0003_support_image.yml +207 -0
- data/tests/fixtures/test_0003_support_instance.yml +206 -0
- data/tests/fixtures/test_0003_support_key.yml +220 -0
- data/tests/fixtures/test_0003_support_realm.yml +195 -0
- data/tests/fixtures/test_0003_support_storage.yml +444 -0
- data/tests/fixtures/test_0003_support_storage_snapshot.yml +196 -0
- data/tests/fixtures/test_0003_support_storage_volume.yml +197 -0
- data/tests/fixtures/test_0003_support_to_change_driver_with_Client.yml +72 -0
- data/tests/fixtures/test_0003_supports_connect.yml +60 -0
- data/tests/fixtures/test_0003_supports_extract_xml_body_using_nokogiri_document.yml +117 -0
- data/tests/fixtures/test_0003_supports_instance.yml +396 -0
- data/tests/fixtures/test_0003_supports_is_compatible_.yml +116 -0
- data/tests/fixtures/test_0003_supports_lunch_image.yml +367 -0
- data/tests/fixtures/test_0003_supports_providers.yml +102 -0
- data/tests/fixtures/test_0003_supports_version.yml +60 -0
- data/tests/fixtures/test_0004_support_architecture.yml +444 -0
- data/tests/fixtures/test_0004_support_create_address.yml +197 -0
- data/tests/fixtures/test_0004_support_create_blob_and_destroy_blob_with_meta_params.yml +139 -0
- data/tests/fixtures/test_0004_support_create_bucket.yml +180 -0
- data/tests/fixtures/test_0004_support_create_bucket_and_destroy_bucket.yml +180 -0
- data/tests/fixtures/test_0004_support_create_firewall_and_destroy_firewall.yml +496 -0
- data/tests/fixtures/test_0004_support_create_image_and_destroy_image.yml +1527 -0
- data/tests/fixtures/test_0004_support_create_instance.yml +115 -0
- data/tests/fixtures/test_0004_support_create_key_and_destroy_key.yml +206 -0
- data/tests/fixtures/test_0004_support_create_volume.yml +105 -0
- data/tests/fixtures/test_0004_support_create_volume_and_destroy_volume.yml +181 -0
- data/tests/fixtures/test_0004_support_to_test_of_valid_DC_connection.yml +60 -0
- data/tests/fixtures/test_0004_supports_current_driver.yml +60 -0
- data/tests/fixtures/test_0004_supports_extract_xml_body_using_nokogiri_element.yml +117 -0
- data/tests/fixtures/test_0004_supports_lunch_image.yml +312 -0
- data/tests/fixtures/test_0004_supports_valid_credentials_.yml +215 -0
- data/tests/fixtures/test_0004_supports_with_config.yml +129 -0
- data/tests/fixtures/test_0005_support_attach_storage_volume.yml +102 -0
- data/tests/fixtures/test_0005_support_attach_storage_volume_and_detach_storage_volume.yml +142 -0
- data/tests/fixtures/test_0005_support_create_instance_with_hwp_id.yml +115 -0
- data/tests/fixtures/test_0005_support_opaque_.yml +152 -0
- data/tests/fixtures/test_0005_supports_current_provider.yml +134 -0
- data/tests/fixtures/test_0005_supports_id.yml +116 -0
- data/tests/fixtures/test_0005_supports_switching_drivers_per_instance.yml +129 -0
- data/tests/fixtures/test_0005_supports_use_driver.yml +60 -0
- data/tests/fixtures/test_0006_support_create_instance_with_realm_id.yml +115 -0
- data/tests/fixtures/test_0006_supports_discovered_.yml +60 -0
- data/tests/fixtures/test_0006_supports_supported_collections.yml +60 -0
- data/tests/fixtures/test_0006_supports_switching_providers_per_instance.yml +208 -0
- data/tests/fixtures/test_0007_support_create_instance_with_name.yml +115 -0
- data/tests/fixtures/test_0007_support_switching_provider_without_credentials.yml +208 -0
- data/tests/fixtures/test_0007_supports_support_.yml +60 -0
- data/tests/fixtures/test_0007_supports_valid_credentials_on_class.yml +370 -0
- data/tests/fixtures/test_0008_support_stop_instance.yml +166 -0
- data/tests/fixtures/test_0008_supports_must_support_.yml +60 -0
- data/tests/fixtures/test_0009_support_start_instance.yml +217 -0
- data/tests/fixtures/test_0009_supports_features.yml +60 -0
- data/tests/fixtures/test_0010_support_reboot_instance.yml +166 -0
- data/tests/fixtures/test_0010_supports_feature_.yml +60 -0
- data/tests/helpers/model_test.rb +33 -0
- data/tests/helpers/xml_test.rb +56 -0
- data/tests/methods/address_test.rb +64 -0
- data/tests/methods/api_test.rb +97 -0
- data/tests/methods/backward_compatibility_test.rb +87 -0
- data/tests/methods/blob_test.rb +64 -0
- data/tests/methods/bucket_test.rb +62 -0
- data/tests/methods/driver_test.rb +48 -0
- data/tests/methods/firewall_test.rb +84 -0
- data/tests/methods/hardware_profile_test.rb +53 -0
- data/tests/methods/image_test.rb +64 -0
- data/tests/methods/instance_state_test.rb +43 -0
- data/tests/methods/instance_test.rb +126 -0
- data/tests/methods/key_test.rb +63 -0
- data/tests/methods/realm_test.rb +50 -0
- data/tests/methods/storage_snapshot_test.rb +53 -0
- data/tests/methods/storage_volume_test.rb +81 -0
- data/tests/models/blob_test.rb +40 -0
- data/tests/models/bucket_test.rb +37 -0
- data/tests/models/driver_test.rb +42 -0
- data/tests/models/hardware_profile_test.rb +80 -0
- data/tests/models/image_test.rb +65 -0
- data/tests/models/storage_volume_test.rb +52 -0
- data/tests/test_helper.rb +59 -11
- metadata +392 -41
- data/lib/base_object.rb +0 -386
- data/lib/client_bucket_methods.rb +0 -69
- data/lib/deltacloud.rb +0 -486
- data/lib/documentation.rb +0 -59
- data/lib/errors.rb +0 -140
- data/lib/hwp_properties.rb +0 -61
- data/tests/buckets_test.rb +0 -141
- data/tests/client_test.rb +0 -59
- data/tests/content_negotiation_test.rb +0 -127
- data/tests/errors_test.rb +0 -57
- data/tests/hardware_profiles_test.rb +0 -75
- data/tests/images_test.rb +0 -102
- data/tests/instance_states_test.rb +0 -66
- data/tests/instances_test.rb +0 -203
- data/tests/keys_test.rb +0 -81
- data/tests/realms_test.rb +0 -64
- data/tests/storage_snapshot_test.rb +0 -76
- data/tests/storage_volume_test.rb +0 -86
data/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# deltacloud-client
|
|
2
|
+
|
|
3
|
+
The Deltacloud project includes a Ruby client. Other language-bindings
|
|
4
|
+
are possible and will be supported soon. The client aims to insulate
|
|
5
|
+
users from having to deal with HTTP and REST directly.
|
|
6
|
+
|
|
7
|
+
Each resource type has an associated model to ease usage. Where
|
|
8
|
+
resource reference other resources, natural navigation across the
|
|
9
|
+
object model is possible.
|
|
10
|
+
|
|
11
|
+
This is a Ruby client library for the [Deltacloud API](http://deltacloud.apache.org).
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
require 'deltacloud/client'
|
|
17
|
+
|
|
18
|
+
API_URL = "http://localhost:3001/api" # Deltacloud API endpoint
|
|
19
|
+
|
|
20
|
+
# Simple use-cases
|
|
21
|
+
client = Deltacloud::Client(API_URL, 'mockuser', 'mockpassword')
|
|
22
|
+
|
|
23
|
+
pp client.instances # List all instances
|
|
24
|
+
pp client.instance('i-12345') # Get one instance
|
|
25
|
+
|
|
26
|
+
inst = client.create_instance 'ami-1234', :hwp_id => 'm1.small' # Create instance
|
|
27
|
+
|
|
28
|
+
inst.reboot! # Reboot instance
|
|
29
|
+
|
|
30
|
+
# Advanced usage
|
|
31
|
+
|
|
32
|
+
# Deltacloud API supports changing driver per-request:
|
|
33
|
+
|
|
34
|
+
client.use(:ec2, 'API_KEY', 'API_SECRET').instances # List EC2 instances
|
|
35
|
+
client.use(:openstack, 'admin@tenant', 'password', KEYSTONE_URL).instances # List Openstack instances
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
# Want help?
|
|
39
|
+
|
|
40
|
+
## Adding new Deltacloud collection to client
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
$ rake generate[YOUR_COLLECTION] # eg. 'storage_snapshot'
|
|
44
|
+
# Hit Enter 2x
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- Edit `lib/deltacloud/client/methods/YOUR_COLLECTION.rb` and add all
|
|
48
|
+
methods for manipulating your collection. The list/show methods
|
|
49
|
+
should already be generated for you, but double-check them.
|
|
50
|
+
|
|
51
|
+
- Edit `lib/deltacloud/client/model/YOUR_COLLECTION.rb` and add model
|
|
52
|
+
methods. Model methods should really be just a syntax sugar and exercise
|
|
53
|
+
the *Deltacloud::Client::Methods* methods.
|
|
54
|
+
The purpose of *model* class life is to deserialize XML body received
|
|
55
|
+
from Deltacloud API to a Ruby class.
|
|
56
|
+
|
|
57
|
+
## Debugging a nasty bug?
|
|
58
|
+
|
|
59
|
+
- You can easily debug deltacloud-client using powerful **pry**.
|
|
60
|
+
|
|
61
|
+
- `gem install deltacloud-core`
|
|
62
|
+
- optional: `rbenv rehash` ;-)
|
|
63
|
+
- `deltacloudd -i mock -p 3002`
|
|
64
|
+
- `rake console`
|
|
65
|
+
|
|
66
|
+
Console require **pry** gem installed. If you are not using this awesome
|
|
67
|
+
gem, you can fix it by `gem install pry`.
|
|
68
|
+
|
|
69
|
+
# License
|
|
70
|
+
|
|
71
|
+
Apache License
|
|
72
|
+
Version 2.0, January 2004
|
|
73
|
+
http://www.apache.org/licenses/
|
data/Rakefile
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#
|
|
2
1
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
3
2
|
# contributor license agreements. See the NOTICE file distributed with
|
|
4
3
|
# this work for additional information regarding copyright ownership. The
|
|
@@ -14,26 +13,110 @@
|
|
|
14
13
|
# License for the specific language governing permissions and limitations
|
|
15
14
|
# under the License.
|
|
16
15
|
|
|
16
|
+
require 'rubygems'
|
|
17
17
|
require 'rubygems/package_task'
|
|
18
|
+
require 'rake'
|
|
18
19
|
require 'rake/testtask'
|
|
19
20
|
|
|
20
|
-
load 'deltacloud-client.gemspec'
|
|
21
|
-
|
|
22
21
|
spec = Gem::Specification.load('deltacloud-client.gemspec')
|
|
23
22
|
|
|
24
23
|
Gem::PackageTask.new(spec) do |pkg|
|
|
25
24
|
pkg.need_tar = true
|
|
26
25
|
end
|
|
27
26
|
|
|
28
|
-
desc "Re-install the deltacloud-client gem"
|
|
27
|
+
desc "Re-install the deltacloud-client gem (used for development)"
|
|
29
28
|
task :reinstall do
|
|
30
29
|
puts %x{gem uninstall deltacloud-client --all -I -x}
|
|
31
30
|
puts %x{gem build deltacloud-client.gemspec}
|
|
32
31
|
puts %x{gem install deltacloud-client-*.gem --local}
|
|
33
32
|
end
|
|
34
33
|
|
|
34
|
+
desc 'Generate model/methods files for collection.'
|
|
35
|
+
task :generate, :name do |t, args|
|
|
36
|
+
require 'erb'
|
|
37
|
+
require_relative './lib/deltacloud/core_ext'
|
|
38
|
+
model_tpl = ERB.new(File.read('support/model_template.erb'))
|
|
39
|
+
methods_tpl = ERB.new(File.read('support/methods_template.erb'))
|
|
40
|
+
name = args[:name]
|
|
41
|
+
model_file = "lib/deltacloud/client/models/#{name}.rb"
|
|
42
|
+
methods_file = "lib/deltacloud/client/methods/#{name}.rb"
|
|
43
|
+
puts model_body = model_tpl.result(binding)
|
|
44
|
+
print "Save model to '#{model_file}'? [Y/n]"
|
|
45
|
+
answer = $stdin.gets.chomp
|
|
46
|
+
if answer.empty? or answer == 'Y'
|
|
47
|
+
File.open(model_file, 'w') { |f|
|
|
48
|
+
f.write(model_body)
|
|
49
|
+
}
|
|
50
|
+
File.open('lib/deltacloud/client/models.rb', 'a') { |f|
|
|
51
|
+
f.puts "require_relative './models/#{name}'"
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
puts methods_body = methods_tpl.result(binding)
|
|
55
|
+
print "Save methods to '#{methods_file}'? [Y/n]"
|
|
56
|
+
answer = $stdin.gets.chomp
|
|
57
|
+
if answer.empty? or answer == 'Y'
|
|
58
|
+
File.open(methods_file, 'w') { |f|
|
|
59
|
+
f.write(methods_body)
|
|
60
|
+
}
|
|
61
|
+
File.open('lib/deltacloud/client/methods.rb', 'a') { |f|
|
|
62
|
+
f.puts "require_relative './methods/#{name}'"
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
puts
|
|
66
|
+
puts "Don't forget to add this line to 'lib/deltacloud/client/connection.rb':"
|
|
67
|
+
puts
|
|
68
|
+
puts "include Deltacloud::Client::Methods::#{name.to_s.camelize}"
|
|
69
|
+
puts
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
desc 'Generate method test file'
|
|
73
|
+
task :test_generate, :name do |t, args|
|
|
74
|
+
require 'erb'
|
|
75
|
+
require_relative './lib/deltacloud/core_ext'
|
|
76
|
+
method_tpl = ERB.new(File.read('support/method_test_template.erb'))
|
|
77
|
+
name = args[:name]
|
|
78
|
+
methods_file = "tests/methods/#{name}_test.rb"
|
|
79
|
+
puts method_body = method_tpl.result(binding)
|
|
80
|
+
print "Save method test to '#{methods_file}'? [Y/n]"
|
|
81
|
+
answer = $stdin.gets.chomp
|
|
82
|
+
if answer.empty? or answer == 'Y'
|
|
83
|
+
File.open(methods_file, 'w') { |f|
|
|
84
|
+
f.write(method_body)
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
desc "Open console with client connected to #{ENV['API_URL'] || 'localhost:3002/api'}"
|
|
91
|
+
task :console do
|
|
92
|
+
require 'pry'
|
|
93
|
+
unless binding.respond_to? :pry
|
|
94
|
+
puts 'To open a console, you need to have "pry" installed (gem install pry)'
|
|
95
|
+
exit(1)
|
|
96
|
+
end
|
|
97
|
+
require_relative './lib/deltacloud/client'
|
|
98
|
+
client = Deltacloud::Client(
|
|
99
|
+
ENV['API_URL'] || 'http://localhost:3002/api',
|
|
100
|
+
ENV['API_USER'] || 'mockuser',
|
|
101
|
+
ENV['API_PASSWORD'] || 'mockpassword'
|
|
102
|
+
)
|
|
103
|
+
binding.pry
|
|
104
|
+
end
|
|
105
|
+
|
|
35
106
|
Rake::TestTask.new(:test) do |t|
|
|
36
107
|
t.test_files = FileList[
|
|
37
|
-
'tests
|
|
108
|
+
'tests/*/*_test.rb'
|
|
38
109
|
]
|
|
39
110
|
end
|
|
111
|
+
|
|
112
|
+
desc "Execute test against live Deltacloud API"
|
|
113
|
+
task :test_live do
|
|
114
|
+
ENV['NO_VCR'] = 'true'
|
|
115
|
+
Rake::Task[:test].invoke
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
desc "Generate test coverage report"
|
|
119
|
+
task :coverage do
|
|
120
|
+
ENV['COVERAGE'] = 'true'
|
|
121
|
+
Rake::Task[:test].invoke
|
|
122
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
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 Client
|
|
18
|
+
require 'require_relative' if RUBY_VERSION < '1.9'
|
|
19
|
+
require 'ostruct'
|
|
20
|
+
require 'nokogiri'
|
|
21
|
+
require 'faraday'
|
|
22
|
+
require 'base64'
|
|
23
|
+
|
|
24
|
+
# Core extensions
|
|
25
|
+
require_relative './core_ext'
|
|
26
|
+
|
|
27
|
+
# Errors && Helpers
|
|
28
|
+
require_relative './client/helpers/model_helper'
|
|
29
|
+
require_relative './client/helpers/xml_helper'
|
|
30
|
+
require_relative './client/helpers/property_helper'
|
|
31
|
+
|
|
32
|
+
# Exceptions goes here
|
|
33
|
+
require_relative './client/base_error'
|
|
34
|
+
|
|
35
|
+
# Faraday Middleware for Deltacloud errors
|
|
36
|
+
require_relative './error_response'
|
|
37
|
+
|
|
38
|
+
# Deltacloud API methods
|
|
39
|
+
require_relative './client/methods/api'
|
|
40
|
+
require_relative './client/methods/backward_compatiblity'
|
|
41
|
+
|
|
42
|
+
# Extend Client module with methods that existed in old client
|
|
43
|
+
# that need to be kept.
|
|
44
|
+
# Deprecation warnings should be provided to users if they use something
|
|
45
|
+
# from these modules.
|
|
46
|
+
#
|
|
47
|
+
extend Deltacloud::Client::Methods::BackwardCompatibility::ClassMethods
|
|
48
|
+
|
|
49
|
+
# Deltacloud methods
|
|
50
|
+
require_relative './client/methods'
|
|
51
|
+
|
|
52
|
+
# Deltacloud models
|
|
53
|
+
require_relative './client/models'
|
|
54
|
+
|
|
55
|
+
require_relative './client/connection'
|
|
56
|
+
|
|
57
|
+
VERSION = '1.1.2'
|
|
58
|
+
|
|
59
|
+
# Check if the connection to Deltacloud API is valid
|
|
60
|
+
def self.valid_connection?(api_url)
|
|
61
|
+
begin
|
|
62
|
+
Deltacloud::Client(api_url, '', '') && true
|
|
63
|
+
rescue Faraday::Error::ConnectionFailed
|
|
64
|
+
false
|
|
65
|
+
rescue Deltacloud::Client::AuthenticationError
|
|
66
|
+
false
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def self.Client(url, api_user, api_password, opts={})
|
|
73
|
+
Client::Connection.new({
|
|
74
|
+
:url => url,
|
|
75
|
+
:api_user => api_user,
|
|
76
|
+
:api_password => api_password
|
|
77
|
+
}.merge(opts))
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
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::Client
|
|
17
|
+
|
|
18
|
+
# Reporting internal client errors
|
|
19
|
+
#
|
|
20
|
+
class Error < StandardError; end
|
|
21
|
+
|
|
22
|
+
class BaseError < Error
|
|
23
|
+
attr_reader :server_backtrace
|
|
24
|
+
attr_reader :driver
|
|
25
|
+
attr_reader :provider
|
|
26
|
+
attr_reader :status
|
|
27
|
+
attr_reader :original_error
|
|
28
|
+
|
|
29
|
+
def initialize(opts={})
|
|
30
|
+
if opts.is_a? Hash
|
|
31
|
+
@server_backtrace = opts[:server_backtrace]
|
|
32
|
+
@driver = opts[:driver]
|
|
33
|
+
@provider = opts[:provider]
|
|
34
|
+
@status = opts[:status]
|
|
35
|
+
@original_error = opts[:original_error]
|
|
36
|
+
super(opts[:message])
|
|
37
|
+
else
|
|
38
|
+
super(opts)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# If the Deltacloud API server error response contain backtrace from
|
|
43
|
+
# server,then make this backtrace available as part of this exception
|
|
44
|
+
# backtrace
|
|
45
|
+
#
|
|
46
|
+
def set_backtrace(backtrace)
|
|
47
|
+
return super(backtrace) if @server_backtrace.nil?
|
|
48
|
+
super([
|
|
49
|
+
backtrace[0..3],
|
|
50
|
+
"-------Deltacloud API backtrace-------",
|
|
51
|
+
@server_backtrace.split[0..10],
|
|
52
|
+
].flatten)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Report 401 errors
|
|
58
|
+
class AuthenticationError < BaseError; end
|
|
59
|
+
|
|
60
|
+
# Report 502 errors (back-end cloud provider encounter error)
|
|
61
|
+
class BackendError < BaseError; end
|
|
62
|
+
|
|
63
|
+
# Report 5xx errors (error on Deltacloud API server)
|
|
64
|
+
class ServerError < BaseError; end
|
|
65
|
+
|
|
66
|
+
# Report 501 errors (collection or operation is not supported)
|
|
67
|
+
class NotSupported < ServerError; end
|
|
68
|
+
|
|
69
|
+
# Report 4xx failures (client failures)
|
|
70
|
+
class ClientFailure < BaseError; end
|
|
71
|
+
|
|
72
|
+
# Report 404 error (object not found)
|
|
73
|
+
class NotFound < BaseError; end
|
|
74
|
+
|
|
75
|
+
# Report 405 failures (resource state does not permit the requested operation)
|
|
76
|
+
class InvalidState < ClientFailure; end
|
|
77
|
+
|
|
78
|
+
# Report this when client do Image#launch using incompatible HWP
|
|
79
|
+
class IncompatibleHardwareProfile < ClientFailure; end
|
|
80
|
+
end
|
|
@@ -0,0 +1,139 @@
|
|
|
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::Client
|
|
17
|
+
class Connection
|
|
18
|
+
|
|
19
|
+
attr_accessor :connection
|
|
20
|
+
attr_reader :request_driver
|
|
21
|
+
attr_reader :request_provider
|
|
22
|
+
attr_reader :entrypoint
|
|
23
|
+
|
|
24
|
+
include Deltacloud::Client::Helpers::Model
|
|
25
|
+
|
|
26
|
+
include Deltacloud::Client::Methods::Address
|
|
27
|
+
include Deltacloud::Client::Methods::Api
|
|
28
|
+
include Deltacloud::Client::Methods::BackwardCompatibility
|
|
29
|
+
include Deltacloud::Client::Methods::Blob
|
|
30
|
+
include Deltacloud::Client::Methods::Bucket
|
|
31
|
+
include Deltacloud::Client::Methods::Common
|
|
32
|
+
include Deltacloud::Client::Methods::Driver
|
|
33
|
+
include Deltacloud::Client::Methods::Firewall
|
|
34
|
+
include Deltacloud::Client::Methods::HardwareProfile
|
|
35
|
+
include Deltacloud::Client::Methods::Image
|
|
36
|
+
include Deltacloud::Client::Methods::Instance
|
|
37
|
+
include Deltacloud::Client::Methods::InstanceState
|
|
38
|
+
include Deltacloud::Client::Methods::Key
|
|
39
|
+
include Deltacloud::Client::Methods::Realm
|
|
40
|
+
include Deltacloud::Client::Methods::StorageSnapshot
|
|
41
|
+
include Deltacloud::Client::Methods::StorageVolume
|
|
42
|
+
include Deltacloud::Client::Methods::LoadBalancer
|
|
43
|
+
include Deltacloud::Client::Methods::Metric
|
|
44
|
+
|
|
45
|
+
def initialize(opts={})
|
|
46
|
+
@request_driver = opts[:driver]
|
|
47
|
+
@request_provider = opts[:provider]
|
|
48
|
+
@connection = Faraday.new(:url => opts[:url]) do |f|
|
|
49
|
+
# NOTE: The order of this is somehow important for VCR
|
|
50
|
+
# recording.
|
|
51
|
+
f.request :url_encoded
|
|
52
|
+
f.headers = deltacloud_request_headers
|
|
53
|
+
f.basic_auth opts[:api_user], opts[:api_password]
|
|
54
|
+
f.use Deltacloud::ErrorResponse
|
|
55
|
+
f.adapter :net_http
|
|
56
|
+
end
|
|
57
|
+
cache_entrypoint!
|
|
58
|
+
@request_driver ||= current_driver
|
|
59
|
+
@request_provider ||= current_provider
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Change the current driver and return copy of the client
|
|
63
|
+
# This allows chained calls like: client.driver(:ec2).instances
|
|
64
|
+
#
|
|
65
|
+
# - driver_id -> The new driver id (:mock, :ec2, :rhevm, ...)
|
|
66
|
+
# - api_user -> API user name
|
|
67
|
+
# - api_password -> API password
|
|
68
|
+
# - api_provider -> API provider (aka API_PROVIDER string)
|
|
69
|
+
#
|
|
70
|
+
def use(driver_id, api_user, api_password, api_provider=nil, &block)
|
|
71
|
+
new_client = self.class.new(
|
|
72
|
+
:url => @connection.url_prefix.to_s,
|
|
73
|
+
:api_user => api_user,
|
|
74
|
+
:api_password => api_password,
|
|
75
|
+
:provider => api_provider,
|
|
76
|
+
:driver => driver_id
|
|
77
|
+
)
|
|
78
|
+
new_client.cache_entrypoint!
|
|
79
|
+
yield new_client if block_given?
|
|
80
|
+
new_client
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Change the API provider but keep the current client credentials.
|
|
84
|
+
# This allows to change the EC2 region and list instances in that
|
|
85
|
+
# region without need to supply credentials.
|
|
86
|
+
#
|
|
87
|
+
# client.use_provider('eu-west-1') { |p| p.instances }
|
|
88
|
+
#
|
|
89
|
+
# - provider_id -> API provider (aka API_PROVIDER)
|
|
90
|
+
#
|
|
91
|
+
def use_provider(provider_id, &block)
|
|
92
|
+
new_client = self.clone
|
|
93
|
+
new_connection = @connection.clone
|
|
94
|
+
new_connection.headers['X-Deltacloud-Provider'] = provider_id
|
|
95
|
+
new_client.connection = new_connection
|
|
96
|
+
new_client.cache_entrypoint!(true)
|
|
97
|
+
yield new_client if block_given?
|
|
98
|
+
new_client
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Cache the API entrypoint (/api) for the current connection,
|
|
102
|
+
# so we don't need to query /api everytime we ask if certain
|
|
103
|
+
# collection/operation is supported
|
|
104
|
+
#
|
|
105
|
+
# - force -> If 'true' force to refresh stored cached entrypoint
|
|
106
|
+
#
|
|
107
|
+
def cache_entrypoint!(force=false)
|
|
108
|
+
@entrypoint = nil if force
|
|
109
|
+
@entrypoint ||= connection.get(path).body
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Check if the credentials used are valid for the current @connection
|
|
113
|
+
#
|
|
114
|
+
def valid_credentials?
|
|
115
|
+
begin
|
|
116
|
+
r = connection.get(path, { :force_auth => 'true' })
|
|
117
|
+
r.status == 200
|
|
118
|
+
rescue error(:authentication_error)
|
|
119
|
+
false
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
private
|
|
124
|
+
|
|
125
|
+
# Default Deltacloud HTTP headers. Common for *all* requests
|
|
126
|
+
# to Deltacloud API
|
|
127
|
+
#
|
|
128
|
+
def deltacloud_request_headers
|
|
129
|
+
headers = {}
|
|
130
|
+
headers['Accept'] = 'application/xml'
|
|
131
|
+
headers['X-Deltacloud-Driver'] = @request_driver.to_s \
|
|
132
|
+
if @request_driver
|
|
133
|
+
headers['X-Deltacloud-Provider'] = @request_provider.to_s \
|
|
134
|
+
if @request_provider
|
|
135
|
+
headers
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
end
|
|
139
|
+
end
|