deltacloud-client 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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/lib/base_object.rb
DELETED
@@ -1,386 +0,0 @@
|
|
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
|
-
require_relative './string.rb'
|
17
|
-
|
18
|
-
module DeltaCloud
|
19
|
-
|
20
|
-
class BaseObjectParamError < Exception; end
|
21
|
-
class NoHandlerForMethod < Exception; end
|
22
|
-
|
23
|
-
# BaseObject model basically provide the basic operation around
|
24
|
-
# REST model, like defining a links between different objects,
|
25
|
-
# element with text values, or collection of these elements
|
26
|
-
class BaseObject
|
27
|
-
attr_reader :id, :url, :client, :base_name
|
28
|
-
attr_reader :objects
|
29
|
-
|
30
|
-
alias :uri :url
|
31
|
-
|
32
|
-
# For initializing new object you require to set
|
33
|
-
# id, url, client and name attribute.
|
34
|
-
def initialize(opts={}, &block)
|
35
|
-
@id, @url, @client, @base_name = opts[:id], opts[:url], opts[:client], opts[:name]
|
36
|
-
@objects = []
|
37
|
-
raise BaseObjectParamError if @id.nil? or @url.nil? or @client.nil? or @base_name.nil?
|
38
|
-
yield self if block_given?
|
39
|
-
end
|
40
|
-
|
41
|
-
# This method add link to another object in REST model
|
42
|
-
# XML syntax: <link rel="destroy" href="http://localhost/api/resource" method="post"/>
|
43
|
-
def add_link!(object_name, id)
|
44
|
-
@objects << {
|
45
|
-
:type => :link,
|
46
|
-
:method_name => object_name.sanitize,
|
47
|
-
:id => id
|
48
|
-
}
|
49
|
-
@objects << {
|
50
|
-
:type => :text,
|
51
|
-
:method_name => "#{object_name.sanitize}_id",
|
52
|
-
:value => id
|
53
|
-
}
|
54
|
-
end
|
55
|
-
|
56
|
-
# Method add property for hardware profile
|
57
|
-
def add_hwp_property!(name, property, type)
|
58
|
-
hwp_property=case type
|
59
|
-
when :float then DeltaCloud::HWP::FloatProperty.new(property, name)
|
60
|
-
when :integer then DeltaCloud::HWP::Property.new(property, name)
|
61
|
-
end
|
62
|
-
@objects << {
|
63
|
-
:type => :property,
|
64
|
-
:method_name => name.sanitize,
|
65
|
-
:property => hwp_property
|
66
|
-
}
|
67
|
-
end
|
68
|
-
|
69
|
-
# This method define text object in REST model
|
70
|
-
# XML syntax: <name>Instance 1</name>
|
71
|
-
def add_text!(object_name, value)
|
72
|
-
@objects << {
|
73
|
-
:type => :text,
|
74
|
-
:method_name => object_name.sanitize,
|
75
|
-
:value => value
|
76
|
-
}
|
77
|
-
end
|
78
|
-
|
79
|
-
def add_authentication!(auth_type, values=[])
|
80
|
-
value = { :key => (values/'login/keyname').text.strip } if auth_type == 'key'
|
81
|
-
if auth_type == 'password'
|
82
|
-
value = {
|
83
|
-
:username => (values/'login/username').text.strip,
|
84
|
-
:username => (values/'login/password').text.strip
|
85
|
-
}
|
86
|
-
end
|
87
|
-
@objects << {
|
88
|
-
:type => :collection,
|
89
|
-
:method_name => 'authentication',
|
90
|
-
:values => value
|
91
|
-
}
|
92
|
-
end
|
93
|
-
|
94
|
-
def add_provider!(provider_id, entrypoints)
|
95
|
-
@providers ||= []
|
96
|
-
@providers << {
|
97
|
-
provider_id.intern => entrypoints.map { |e| { :kind => e[:kind], :url => e.text } }
|
98
|
-
}
|
99
|
-
@objects << {
|
100
|
-
:type => :collection,
|
101
|
-
:method_name => 'providers',
|
102
|
-
:values => @providers
|
103
|
-
}
|
104
|
-
end
|
105
|
-
|
106
|
-
|
107
|
-
# This method define collection of text elements inside REST model
|
108
|
-
# XML syntax: <addresses>
|
109
|
-
# <address>127.0.0.1</address>
|
110
|
-
# <address>127.0.0.2</address>
|
111
|
-
# </addresses>
|
112
|
-
def add_addresses!(collection_name, values=[])
|
113
|
-
@objects << {
|
114
|
-
:type => :collection,
|
115
|
-
:method_name => collection_name.sanitize,
|
116
|
-
:values => values.collect { |v| { :address => v.text.strip, :type => v[:type] }}
|
117
|
-
}
|
118
|
-
end
|
119
|
-
|
120
|
-
# This method define collection of text elements inside REST model
|
121
|
-
# XML syntax: <addresses>
|
122
|
-
# <address>127.0.0.1</address>
|
123
|
-
# <address>127.0.0.2</address>
|
124
|
-
# </addresses>
|
125
|
-
def add_collection!(collection_name, values=[])
|
126
|
-
@objects << {
|
127
|
-
:type => :collection,
|
128
|
-
:method_name => collection_name.sanitize,
|
129
|
-
:values => values
|
130
|
-
}
|
131
|
-
end
|
132
|
-
|
133
|
-
# Basic method hander. This define a way how value from property
|
134
|
-
# will be returned
|
135
|
-
def method_handler(m, args=[])
|
136
|
-
case m[:type]
|
137
|
-
when :link then return @client.send(m[:method_name].singularize, m[:id])
|
138
|
-
when :text then return m[:value]
|
139
|
-
when :property then return m[:property]
|
140
|
-
when :collection then return m[:values]
|
141
|
-
when :list then return m[:value].join(", ")
|
142
|
-
else raise NoHandlerForMethod
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def method_missing(method_name, *args)
|
147
|
-
# First of all search throught array for method name
|
148
|
-
m = search_for_method(method_name)
|
149
|
-
if m.nil?
|
150
|
-
if method_name == :"valid_provider?"
|
151
|
-
return providers.any? { |p| p.keys.include? args.first.to_sym }
|
152
|
-
end
|
153
|
-
if method_name == :"valid_provider_url?"
|
154
|
-
return providers.any? { |p| !p.find { |k, v| v.find { |u| u[:url] == args.first } }.nil? }
|
155
|
-
end
|
156
|
-
super
|
157
|
-
else
|
158
|
-
# Call appropriate handler for method
|
159
|
-
method_handler(m, args)
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
# This method adds blobs to the blob_list property
|
164
|
-
# of a bucket
|
165
|
-
def add_blob!(blob_name)
|
166
|
-
if @blob_list.nil?
|
167
|
-
@blob_list = [blob_name]
|
168
|
-
@objects << {
|
169
|
-
:type => :list,
|
170
|
-
:method_name => "blob_list",
|
171
|
-
:value => @blob_list
|
172
|
-
}
|
173
|
-
else
|
174
|
-
@blob_list << blob_name
|
175
|
-
current = search_for_method('blob_list')
|
176
|
-
current[:value] = @blob_list
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
private
|
181
|
-
|
182
|
-
def search_for_method(name)
|
183
|
-
@objects.detect { |o| o[:method_name] == "#{name}" }
|
184
|
-
end
|
185
|
-
|
186
|
-
end
|
187
|
-
|
188
|
-
class ActionObject < BaseObject
|
189
|
-
|
190
|
-
def initialize(opts={}, &block)
|
191
|
-
super(opts)
|
192
|
-
@action_urls = opts[:action_urls] || []
|
193
|
-
@actions = []
|
194
|
-
end
|
195
|
-
|
196
|
-
# This trigger is called right after action.
|
197
|
-
# This method does nothing inside ActionObject
|
198
|
-
# but it can be redifined and used in meta-programming
|
199
|
-
def action_trigger(action)
|
200
|
-
end
|
201
|
-
|
202
|
-
def add_action_link!(id, link)
|
203
|
-
m = {
|
204
|
-
:type => :action_link,
|
205
|
-
:method_name => "#{link['rel'].sanitize}!",
|
206
|
-
:id => id,
|
207
|
-
:href => link['href'],
|
208
|
-
:rel => link['rel'].sanitize,
|
209
|
-
:method => link['method'].sanitize
|
210
|
-
}
|
211
|
-
@objects << m
|
212
|
-
@actions << [m[:rel], m[:href]]
|
213
|
-
@action_urls << m[:href]
|
214
|
-
end
|
215
|
-
|
216
|
-
def actions
|
217
|
-
@objects.inject([]) do |result, item|
|
218
|
-
result << [item[:rel], item[:href]] if item[:type].eql?(:action_link)
|
219
|
-
result
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
def action_urls
|
224
|
-
actions.collect { |a| a.last }
|
225
|
-
end
|
226
|
-
|
227
|
-
alias :base_method_handler :method_handler
|
228
|
-
|
229
|
-
# First call BaseObject method handler,
|
230
|
-
# then, if not method found try ActionObject handler
|
231
|
-
def method_handler(m, args=[])
|
232
|
-
begin
|
233
|
-
base_method_handler(m, args)
|
234
|
-
rescue NoHandlerForMethod
|
235
|
-
case m[:type]
|
236
|
-
when :action_link then do_action(m, args)
|
237
|
-
else raise NoHandlerForMethod
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
alias :original_method_missing :method_missing
|
243
|
-
|
244
|
-
def method_missing(name, *args)
|
245
|
-
if name.to_s =~ /^has_(\w+)\?$/
|
246
|
-
return actions.any? { |a| a[0] == $1 }
|
247
|
-
end
|
248
|
-
original_method_missing(name, args)
|
249
|
-
end
|
250
|
-
|
251
|
-
private
|
252
|
-
|
253
|
-
def do_action(m, args)
|
254
|
-
args = args.first || {}
|
255
|
-
method = m[:method].to_sym
|
256
|
-
@client.request(method,
|
257
|
-
m[:href],
|
258
|
-
method == :get ? args : {},
|
259
|
-
method == :get ? {} : args)
|
260
|
-
action_trigger(m[:rel])
|
261
|
-
end
|
262
|
-
|
263
|
-
end
|
264
|
-
|
265
|
-
class StatefulObject < ActionObject
|
266
|
-
attr_reader :state
|
267
|
-
|
268
|
-
def initialize(opts={}, &block)
|
269
|
-
super(opts)
|
270
|
-
@state = opts[:initial_state] || ''
|
271
|
-
add_default_states!
|
272
|
-
end
|
273
|
-
|
274
|
-
def add_default_states!
|
275
|
-
@objects << {
|
276
|
-
:method_name => 'stopped?',
|
277
|
-
:type => :state,
|
278
|
-
:state => 'STOPPED'
|
279
|
-
}
|
280
|
-
@objects << {
|
281
|
-
:method_name => 'running?',
|
282
|
-
:type => :state,
|
283
|
-
:state => 'RUNNING'
|
284
|
-
}
|
285
|
-
@objects << {
|
286
|
-
:method_name => 'pending?',
|
287
|
-
:type => :state,
|
288
|
-
:state => 'PENDING'
|
289
|
-
}
|
290
|
-
@objects << {
|
291
|
-
:method_name => 'shutting_down?',
|
292
|
-
:type => :state,
|
293
|
-
:state => 'SHUTTING_DOWN'
|
294
|
-
}
|
295
|
-
end
|
296
|
-
|
297
|
-
def action_trigger(action)
|
298
|
-
# Refresh object state after action unless the object was destroyed
|
299
|
-
return if action.to_s == "destroy"
|
300
|
-
@new_state_object = @client.send(self.base_name, self.id)
|
301
|
-
@state = @new_state_object.state
|
302
|
-
self.update_actions!
|
303
|
-
end
|
304
|
-
|
305
|
-
def add_run_action!(id, link)
|
306
|
-
@objects << {
|
307
|
-
:method_name => 'run',
|
308
|
-
:type => :run,
|
309
|
-
:url => link,
|
310
|
-
}
|
311
|
-
end
|
312
|
-
|
313
|
-
alias :action_method_handler :method_handler
|
314
|
-
|
315
|
-
def method_handler(m, args=[])
|
316
|
-
begin
|
317
|
-
action_method_handler(m, args)
|
318
|
-
rescue NoHandlerForMethod
|
319
|
-
case m[:type]
|
320
|
-
when :state then evaluate_state(m[:state], @state)
|
321
|
-
when :run then run_command(m[:url][:href], args)
|
322
|
-
else raise NoHandlerForMethod
|
323
|
-
end
|
324
|
-
end
|
325
|
-
end
|
326
|
-
|
327
|
-
# private
|
328
|
-
|
329
|
-
def run_command(instance_url, args)
|
330
|
-
credentials = args[1]
|
331
|
-
params = {
|
332
|
-
:cmd => args[0],
|
333
|
-
:private_key => credentials[:pem] ? File.read(credentials[:pem]) : nil,
|
334
|
-
}
|
335
|
-
params.merge!({
|
336
|
-
:username => credentials[:username],
|
337
|
-
:password => credentials[:password]
|
338
|
-
}) if credentials[:username] and credentials[:password]
|
339
|
-
@client.request(:post, instance_url, {}, params) do |response|
|
340
|
-
output = Nokogiri::XML(response)
|
341
|
-
(output/'/instance/output').first.text
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
def evaluate_state(method_state, current_state)
|
346
|
-
method_state.eql?(current_state)
|
347
|
-
end
|
348
|
-
|
349
|
-
def action_objects
|
350
|
-
@objects.select { |o| o[:type] == :action_link }
|
351
|
-
end
|
352
|
-
|
353
|
-
def update_actions!
|
354
|
-
new_actions = @new_state_object.action_objects
|
355
|
-
@objects.reject! { |o| o[:type] == :action_link }
|
356
|
-
@objects = (@objects + new_actions)
|
357
|
-
end
|
358
|
-
|
359
|
-
end
|
360
|
-
|
361
|
-
def self.add_class(name, parent=:base)
|
362
|
-
parent = parent.to_s
|
363
|
-
parent_class = "#{parent.classify}Object"
|
364
|
-
@defined_classes ||= []
|
365
|
-
class_name = "#{parent.classify}::#{name.classify}"
|
366
|
-
unless @defined_classes.include?(class_name)
|
367
|
-
DeltaCloud::API.class_eval("class #{class_name} < DeltaCloud::#{parent_class}; end")
|
368
|
-
@defined_classes << class_name
|
369
|
-
end
|
370
|
-
|
371
|
-
DeltaCloud::API.const_get(parent.classify).const_get(name.classify)
|
372
|
-
end
|
373
|
-
|
374
|
-
def self.guess_model_type(response)
|
375
|
-
response = Nokogiri::XML(response.to_s)
|
376
|
-
return :action if ((response/'//actions').length >= 1) and ((response/'//state').length == 0)
|
377
|
-
return :stateful if ((response/'//actions').length >= 1) and ((response/'//state').length >= 1)
|
378
|
-
return :base
|
379
|
-
end
|
380
|
-
|
381
|
-
class API
|
382
|
-
class Action; end
|
383
|
-
class Base; end
|
384
|
-
class Stateful; end
|
385
|
-
end
|
386
|
-
end
|
@@ -1,69 +0,0 @@
|
|
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 ClientBucketMethods
|
17
|
-
|
18
|
-
def create_bucket(params)
|
19
|
-
obj = nil
|
20
|
-
request(:post, "#{api_uri.to_s}/buckets", {:name => params['id'],:location=>params['bucket_location'] }) do |response|
|
21
|
-
handle_backend_error(response) if response.code!=201
|
22
|
-
obj = base_object(:bucket, response)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def destroy_bucket(params)
|
27
|
-
#actually response here is 204 - no content - so nothing returned to client?
|
28
|
-
request(:delete, "#{api_uri.to_s}/buckets/#{params['id']}") do |response|
|
29
|
-
handle_backend_error(response) if response.code!=204
|
30
|
-
nil if response.code == 204
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def create_blob(params)
|
35
|
-
blob = nil
|
36
|
-
resource = RestClient::Resource.new("#{api_uri.to_s}/buckets/#{params['bucket']}", :open_timeout => 10, :timeout => 45)
|
37
|
-
headers = default_headers.merge(extended_headers)
|
38
|
-
unless params['metadata'].nil?
|
39
|
-
metadata_headers = {}
|
40
|
-
params['metadata'].each do |k,v|
|
41
|
-
metadata_headers["X-Deltacloud-Blobmeta-#{k}"] = v
|
42
|
-
end
|
43
|
-
headers = headers.merge(metadata_headers)
|
44
|
-
end
|
45
|
-
resource.send(:post, {:blob_data => File.new(params['file_path'], 'rb'), :blob_id => params[:id]}, headers) do |response, request, block|
|
46
|
-
handle_backend_error(response) if response.code.eql?(500)
|
47
|
-
blob = base_object(:blob, response)
|
48
|
-
yield blob if block_given?
|
49
|
-
end
|
50
|
-
return blob
|
51
|
-
end
|
52
|
-
|
53
|
-
def destroy_blob(params)
|
54
|
-
request(:delete, "#{api_uri.to_s}/buckets/#{params['bucket']}/#{params[:id]}") do |response|
|
55
|
-
handle_backend_error(response) if response.code!=204
|
56
|
-
nil if response.code == 204
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
#RestClient doesn't do streaming 'get' yet - we already opened a pull request on this see
|
61
|
-
#https://github.com/archiloque/rest-client/issues/closed#issue/62 - apparently its going to
|
62
|
-
#be in the next version - unknown when. For now get full response. FIXME
|
63
|
-
def blob_data(params)
|
64
|
-
request(:get, "#{api_uri.to_s}/buckets/#{params['bucket']}/#{params[:id]}/content") do |response|
|
65
|
-
response
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|