softlayer_api 2.2.2 → 3.0.b1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.textile +9 -5
- data/examples/account_servers.rb +2 -2
- data/examples/create_ticket.rb +3 -3
- data/examples/open_tickets.rb +2 -2
- data/examples/ticket_info.rb +2 -2
- data/lib/softlayer/APIParameterFilter.rb +7 -21
- data/lib/softlayer/Account.rb +28 -19
- data/lib/softlayer/BareMetalServer.rb +13 -25
- data/lib/softlayer/BareMetalServerOrder.rb +6 -23
- data/lib/softlayer/BareMetalServerOrder_Package.rb +11 -29
- data/lib/softlayer/Client.rb +17 -23
- data/lib/softlayer/Config.rb +6 -22
- data/lib/softlayer/Datacenter.rb +53 -0
- data/lib/softlayer/DynamicAttribute.rb +3 -19
- data/lib/softlayer/ImageTemplate.rb +384 -0
- data/lib/softlayer/ModelBase.rb +4 -20
- data/lib/softlayer/ObjectFilter.rb +193 -191
- data/lib/softlayer/ObjectMaskParser.rb +3 -19
- data/lib/softlayer/ObjectMaskProperty.rb +3 -19
- data/lib/softlayer/ObjectMaskToken.rb +3 -19
- data/lib/softlayer/ObjectMaskTokenizer.rb +3 -19
- data/lib/softlayer/ProductItemCategory.rb +6 -23
- data/lib/softlayer/ProductPackage.rb +11 -32
- data/lib/softlayer/Server.rb +22 -19
- data/lib/softlayer/Ticket.rb +6 -45
- data/lib/softlayer/VirtualServer.rb +24 -101
- data/lib/softlayer/VirtualServerOrder.rb +14 -31
- data/lib/softlayer/VirtualServerUpgradeOrder.rb +142 -0
- data/lib/softlayer/base.rb +11 -30
- data/lib/softlayer/object_mask_helpers.rb +3 -19
- data/lib/softlayer_api.rb +12 -22
- metadata +7 -4
data/lib/softlayer/Config.rb
CHANGED
@@ -1,34 +1,18 @@
|
|
1
|
-
|
1
|
+
#--
|
2
2
|
# Copyright (c) 2014 SoftLayer Technologies, Inc. All rights reserved.
|
3
3
|
#
|
4
|
-
#
|
5
|
-
|
6
|
-
# in the Software without restriction, including without limitation the rights
|
7
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
-
# copies of the Software, and to permit persons to whom the Software is
|
9
|
-
# furnished to do so, subject to the following conditions:
|
10
|
-
#
|
11
|
-
# The above copyright notice and this permission notice shall be included in
|
12
|
-
# all copies or substantial portions of the Software.
|
13
|
-
#
|
14
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
-
# THE SOFTWARE.
|
21
|
-
#
|
4
|
+
# For licensing information see the LICENSE.md file in the project root.
|
5
|
+
#++
|
22
6
|
|
23
7
|
require 'configparser'
|
24
8
|
|
25
9
|
module SoftLayer
|
26
10
|
|
27
|
-
# The SoftLayer Config class is responsible for providing the key information
|
11
|
+
# The SoftLayer Config class is responsible for providing the key information
|
28
12
|
# the library needs to communicate with the network SoftLayer API. Those three crucial
|
29
13
|
# pieces of information are the Username, the API Key, and the endpoint_url. This information
|
30
14
|
# is collected in a hash with the keys `:username`, `:api_key`, and `:endpoint_url` repsectively.
|
31
|
-
#
|
15
|
+
#
|
32
16
|
# The routine used to retrieve this information from a Config object is Config.client_settings
|
33
17
|
#
|
34
18
|
# There are several locations that the Config class looks for this information:
|
@@ -58,7 +42,7 @@ module SoftLayer
|
|
58
42
|
#
|
59
43
|
# = Environment Variables
|
60
44
|
#
|
61
|
-
# The config class will search the environment variables SL_USERNAME and SL_API_KEY for
|
45
|
+
# The config class will search the environment variables SL_USERNAME and SL_API_KEY for
|
62
46
|
# the username and API key respectively. The endpoint_url may not be set thorugh
|
63
47
|
# environment variables.
|
64
48
|
#
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2014 SoftLayer Technologies, Inc. All rights reserved.
|
3
|
+
#
|
4
|
+
# For licensing information see the LICENSE.md file in the project root.
|
5
|
+
#++
|
6
|
+
|
7
|
+
module SoftLayer
|
8
|
+
##
|
9
|
+
# A Data Center in the SoftLayer network
|
10
|
+
#
|
11
|
+
# This class corresponds to the SoftLayer_Location++ data type:
|
12
|
+
#
|
13
|
+
# http://sldn.softlayer.com/reference/datatypes/SoftLayer_Location
|
14
|
+
#
|
15
|
+
# Although in this context it is used to represent a data center and
|
16
|
+
# not the more general class of locations that that data type can
|
17
|
+
# represent.
|
18
|
+
|
19
|
+
class Datacenter < SoftLayer::ModelBase
|
20
|
+
sl_attr :name
|
21
|
+
sl_attr :long_name, "longName"
|
22
|
+
|
23
|
+
##
|
24
|
+
# Return the datacenter with the given name ('sng01' or 'dal05')
|
25
|
+
def self.datacenter_named(name, client = nil)
|
26
|
+
datacenters(client).find{ | datacenter | datacenter.name == name.to_s.downcase }
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Return a list of all the datacenters
|
31
|
+
#
|
32
|
+
# If the client parameter is not provided, the routine
|
33
|
+
# will try to use Client::defult_client. If no client
|
34
|
+
# can be found, the routine will raise an exception
|
35
|
+
#
|
36
|
+
# This routine will only retrieve the list of datacenters from
|
37
|
+
# the network once and keep it in memory unless you
|
38
|
+
# pass in force_reload as true.
|
39
|
+
#
|
40
|
+
@@data_centers = nil
|
41
|
+
def self.datacenters(client = nil, force_reload = false)
|
42
|
+
softlayer_client = client || Client.default_client
|
43
|
+
raise "Datacenter.datacenters requires a client to call the network API" if !softlayer_client
|
44
|
+
|
45
|
+
if(!@@data_centers || force_reload)
|
46
|
+
datacenters_data = softlayer_client[:Location].getDatacenters
|
47
|
+
@@data_centers = datacenters_data.collect { | datacenter_data | self.new(softlayer_client, datacenter_data) }
|
48
|
+
end
|
49
|
+
|
50
|
+
@@data_centers
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,24 +1,8 @@
|
|
1
|
-
|
1
|
+
#--
|
2
2
|
# Copyright (c) 2014 SoftLayer Technologies, Inc. All rights reserved.
|
3
3
|
#
|
4
|
-
#
|
5
|
-
|
6
|
-
# in the Software without restriction, including without limitation the rights
|
7
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
-
# copies of the Software, and to permit persons to whom the Software is
|
9
|
-
# furnished to do so, subject to the following conditions:
|
10
|
-
#
|
11
|
-
# The above copyright notice and this permission notice shall be included in
|
12
|
-
# all copies or substantial portions of the Software.
|
13
|
-
#
|
14
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
-
# THE SOFTWARE.
|
21
|
-
#
|
4
|
+
# For licensing information see the LICENSE.md file in the project root.
|
5
|
+
#++
|
22
6
|
|
23
7
|
module SoftLayer
|
24
8
|
|
@@ -0,0 +1,384 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2014 SoftLayer Technologies, Inc. All rights reserved.
|
3
|
+
#
|
4
|
+
# For licensing information see the LICENSE.md file in the project root.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
module SoftLayer
|
9
|
+
##
|
10
|
+
# A Virtual Server Image Template.
|
11
|
+
#
|
12
|
+
# This class rougly corresponds to the unwieldily named
|
13
|
+
# +SoftLayer_Virtual_Guest_Block_Device_Template_Group+
|
14
|
+
# service:
|
15
|
+
#
|
16
|
+
# http://sldn.softlayer.com/reference/services/SoftLayer_Virtual_Guest_Block_Device_Template_Group
|
17
|
+
#
|
18
|
+
#
|
19
|
+
class ImageTemplate < SoftLayer::ModelBase
|
20
|
+
##
|
21
|
+
# :attr_reader:
|
22
|
+
# The 'friendly name' given to the template when it was created
|
23
|
+
sl_attr :name
|
24
|
+
|
25
|
+
##
|
26
|
+
# :attr_reader:
|
27
|
+
# The notes, if any, that are attached to the template. Can be nil.
|
28
|
+
sl_attr :notes, "note"
|
29
|
+
|
30
|
+
##
|
31
|
+
# :attr_reader:
|
32
|
+
# The universally unique identifier (if any) for the template. Can be nil.
|
33
|
+
sl_attr :global_id, 'globalIdentifier'
|
34
|
+
|
35
|
+
# Change the name of the template
|
36
|
+
def rename!(new_name)
|
37
|
+
self.service.editObject({ "name" => new_name.to_s})
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# true if the image template is a flex image
|
42
|
+
# Note that the publicFlag property comes back as an integer (0 or 1)
|
43
|
+
def public?
|
44
|
+
self["publicFlag"] != 0
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# true if the image template is a flex image
|
49
|
+
# Note that the flexImageFlag property comes back as a boolean
|
50
|
+
def flex_image?
|
51
|
+
!!self["flexImageFlag"]
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Changes the notes on an template to be the given strings
|
56
|
+
def notes=(new_notes)
|
57
|
+
# it is not a typo that this sets the "note" property. The
|
58
|
+
# property in the network api is "note", the model exposes it as
|
59
|
+
# 'notes' for self-consistency
|
60
|
+
self.service.editObject({ "note" => new_notes.to_s})
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Returns an array of the tags set on the image
|
65
|
+
def tags
|
66
|
+
return self["tagReferences"].collect{ |tag_reference| tag_reference["tag"]["name"] }
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# Sets the tags on the template. Note: a pre-existing tag will be
|
71
|
+
# removed from the template if it does not appear in the array given.
|
72
|
+
# The list of tags must be comprehensive.
|
73
|
+
def tags=(tags_array)
|
74
|
+
as_strings = tags_array.collect { |tag| tag.to_s }
|
75
|
+
self.service.setTags(as_strings.join(','))
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Returns the an array containing the datacenters where this image is available.
|
80
|
+
def datacenters
|
81
|
+
self["datacenters"].collect{ |datacenter_data| SoftLayer::Datacenter.datacenter_named(datacenter_data["name"])}
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Accepts an array of datacenters (instances of SoftLayer::Datacenter) where this
|
86
|
+
# image should be made available. The call will kick off one or more transactions
|
87
|
+
# to make the image available in the given datacenters. These transactions can take
|
88
|
+
# some time to complete.
|
89
|
+
#
|
90
|
+
# Note that the template will be REMOVED from any datacenter that does not
|
91
|
+
# appear in this array! The list given must be comprehensive.
|
92
|
+
#
|
93
|
+
# The available_datacenters call returns a list of the values that are valid
|
94
|
+
# whithin this array.
|
95
|
+
def datacenters=(datacenters_array)
|
96
|
+
datacenter_data = datacenters_array.collect do |datacenter|
|
97
|
+
{ "id" => datacenter.id }
|
98
|
+
end
|
99
|
+
|
100
|
+
self.service.setAvailableLocations(datacenter_data.compact)
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Returns an array of the datacenters that this image can be stored in.
|
105
|
+
# This is the set of datacenters that you may choose from, when putting
|
106
|
+
# together a list you will send to the datacenters= setter.
|
107
|
+
#
|
108
|
+
def available_datacenters
|
109
|
+
datacenters_data = self.service.getStorageLocations()
|
110
|
+
datacenters_data.collect { |datacenter_data| SoftLayer::Datacenter.datacenter_named(datacenter_data["name"]) }
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
##
|
115
|
+
# Returns a list of the accounts (identified by account ID numbers)
|
116
|
+
# that this image is shared with
|
117
|
+
def shared_with_accounts
|
118
|
+
accounts_data = self.service.getAccountReferences
|
119
|
+
accounts_data.collect { |account_data| account_data["accountId"] }
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Change the set of accounts that this image is shared with.
|
124
|
+
# The parameter is an array of account ID's.
|
125
|
+
#
|
126
|
+
# Note that this routine will "unshare" with any accounts
|
127
|
+
# not included in the list passed in so the list should
|
128
|
+
# be comprehensive
|
129
|
+
#
|
130
|
+
def shared_with_accounts= (account_id_list)
|
131
|
+
already_sharing_with = self.shared_with_accounts
|
132
|
+
|
133
|
+
accounts_to_add = account_id_list.select { |account_id| !already_sharing_with.include?(account_id) }
|
134
|
+
|
135
|
+
# Note, using the network API, it is possible to "unshare" an image template
|
136
|
+
# with the account that owns it, however, this leads to a rather odd state
|
137
|
+
# where the image has allocated resources (that the account may be charged for)
|
138
|
+
# but no way to delete those resources. For that reason this model
|
139
|
+
# always includes the account ID that owns the image in the list of
|
140
|
+
# accounts the image will be shared with.
|
141
|
+
my_account_id = self['accountId']
|
142
|
+
accounts_to_add.push(my_account_id) if !already_sharing_with.include?(my_account_id) && !accounts_to_add.include?(my_account_id)
|
143
|
+
|
144
|
+
accounts_to_remove = already_sharing_with.select { |account_id| (account_id != my_account_id) && !account_id_list.include?(account_id) }
|
145
|
+
|
146
|
+
accounts_to_add.each {|account_id| self.service.permitSharingAccess account_id }
|
147
|
+
accounts_to_remove.each {|account_id| self.service.denySharingAccess account_id }
|
148
|
+
end
|
149
|
+
|
150
|
+
##
|
151
|
+
# Creates a transaction to delete the image template and
|
152
|
+
# all the disk images associated with it.
|
153
|
+
#
|
154
|
+
# This is a final action and cannot be undone.
|
155
|
+
# the transaction will proceed immediately.
|
156
|
+
#
|
157
|
+
# Call it with extreme care!
|
158
|
+
def delete!
|
159
|
+
self.service.deleteObject
|
160
|
+
end
|
161
|
+
|
162
|
+
##
|
163
|
+
# Repeatedly poll the netwokr API until transactions related to this image
|
164
|
+
# template are finished
|
165
|
+
#
|
166
|
+
# A template is not 'ready' until all the transactions on the template
|
167
|
+
# itself, and all its children are complete.
|
168
|
+
#
|
169
|
+
# At each trial, the routine will yield to a block if one is given
|
170
|
+
# The block is passed one parameter, a boolean flag indicating
|
171
|
+
# whether or not the image template is 'ready'.
|
172
|
+
#
|
173
|
+
def wait_until_ready(max_trials, seconds_between_tries = 2)
|
174
|
+
# pessimistically assume the server is not ready
|
175
|
+
num_trials = 0
|
176
|
+
begin
|
177
|
+
self.refresh_details()
|
178
|
+
|
179
|
+
parent_ready = !(has_sl_property? :transactionId) || (self[:transactionId] == "")
|
180
|
+
children_ready = (nil == self["children"].find { |child| child["transactionId"] != "" })
|
181
|
+
|
182
|
+
ready = parent_ready && children_ready
|
183
|
+
yield ready if block_given?
|
184
|
+
|
185
|
+
num_trials = num_trials + 1
|
186
|
+
sleep(seconds_between_tries) if !ready && (num_trials <= max_trials)
|
187
|
+
end until ready || (num_trials >= max_trials)
|
188
|
+
|
189
|
+
ready
|
190
|
+
end
|
191
|
+
|
192
|
+
# ModelBase protocol methods
|
193
|
+
def service
|
194
|
+
softlayer_client['Virtual_Guest_Block_Device_Template_Group'].object_with_id(self.id)
|
195
|
+
end
|
196
|
+
|
197
|
+
def softlayer_properties(object_mask = nil)
|
198
|
+
self.service.object_mask(self.class.default_object_mask).getObject
|
199
|
+
end
|
200
|
+
|
201
|
+
##
|
202
|
+
# Retrieve a list of the private image templates from the account.
|
203
|
+
#
|
204
|
+
# The options parameter should contain:
|
205
|
+
#
|
206
|
+
# <b>+:client+</b> - The client used to connect to the API
|
207
|
+
#
|
208
|
+
# If no client is given, then the routine will try to use Client.default_client.
|
209
|
+
# If no client can be found the routine will raise an error.
|
210
|
+
#
|
211
|
+
# Additional options that may be provided:
|
212
|
+
# * <b>+:name+</b> (string) - Return templates with the given name
|
213
|
+
# * <b>+:global_id+</b> (string) - Return templates with the given global identfier
|
214
|
+
def self.find_private_templates(options_hash = {})
|
215
|
+
softlayer_client = options_hash[:client] || Client.default_client
|
216
|
+
raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !softlayer_client
|
217
|
+
|
218
|
+
if(options_hash.has_key? :object_filter)
|
219
|
+
object_filter = options_hash[:object_filter]
|
220
|
+
raise "Expected an instance of SoftLayer::ObjectFilter" unless object_filter.kind_of?(SoftLayer::ObjectFilter)
|
221
|
+
else
|
222
|
+
object_filter = ObjectFilter.new()
|
223
|
+
end
|
224
|
+
|
225
|
+
option_to_filter_path = {
|
226
|
+
:name => "privateBlockDeviceTemplateGroups.name",
|
227
|
+
:global_id => "privateBlockDeviceTemplateGroups.globalIdentifier",
|
228
|
+
}
|
229
|
+
|
230
|
+
# For each of the options in the option_to_filter_path map, if the options hash includes
|
231
|
+
# that particular option, add a clause to the object filter that filters for the matching
|
232
|
+
# value
|
233
|
+
option_to_filter_path.each do |option, filter_path|
|
234
|
+
object_filter.modify { |filter| filter.accept(filter_path).when_it is(options_hash[option])} if options_hash[option]
|
235
|
+
end
|
236
|
+
|
237
|
+
# Tags get a much more complex object filter operation so we handle them separately
|
238
|
+
if options_hash.has_key?(:tags)
|
239
|
+
object_filter.set_criteria_for_key_path("privateBlockDeviceTemplateGroups.tagReferences.tag.name", {
|
240
|
+
'operation' => 'in',
|
241
|
+
'options' => [{
|
242
|
+
'name' => 'data',
|
243
|
+
'value' => options_hash[:tags].collect{ |tag_value| tag_value.to_s }
|
244
|
+
}]
|
245
|
+
} );
|
246
|
+
end
|
247
|
+
|
248
|
+
account_service = softlayer_client['Account']
|
249
|
+
account_service = account_service.object_filter(object_filter) unless object_filter.empty?
|
250
|
+
account_service = account_service.object_mask(default_object_mask)
|
251
|
+
|
252
|
+
if options_hash.has_key? :object_mask
|
253
|
+
account_service = account_service.object_mask(options_hash[:object_mask])
|
254
|
+
end
|
255
|
+
|
256
|
+
if options_hash.has_key?(:result_limit)
|
257
|
+
offset = options[:result_limit][:offset]
|
258
|
+
limit = options[:result_limit][:limit]
|
259
|
+
|
260
|
+
account_service = account_service.result_limit(offset, limit)
|
261
|
+
end
|
262
|
+
|
263
|
+
templates_data = account_service.getPrivateBlockDeviceTemplateGroups
|
264
|
+
templates_data.collect { |template_data| new(softlayer_client, template_data) }
|
265
|
+
end
|
266
|
+
|
267
|
+
##
|
268
|
+
# Retrieve a list of public image templates
|
269
|
+
#
|
270
|
+
# The options parameter should contain:
|
271
|
+
#
|
272
|
+
# <b>+:client+</b> - The client used to connect to the API
|
273
|
+
#
|
274
|
+
# If no client is given, then the routine will try to use Client.default_client
|
275
|
+
# If no client can be found the routine will raise an error.
|
276
|
+
#
|
277
|
+
# Additional options that may be provided:
|
278
|
+
# * <b>+:name+</b> (string) - Return templates with the given name
|
279
|
+
# * <b>+:global_id+</b> (string) - Return templates with the given global identfier
|
280
|
+
def self.find_public_templates(options_hash = {})
|
281
|
+
softlayer_client = options_hash[:client] || Client.default_client
|
282
|
+
raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !softlayer_client
|
283
|
+
|
284
|
+
if(options_hash.has_key? :object_filter)
|
285
|
+
object_filter = options_hash[:object_filter]
|
286
|
+
raise "Expected an instance of SoftLayer::ObjectFilter" unless object_filter.kind_of?(SoftLayer::ObjectFilter)
|
287
|
+
else
|
288
|
+
object_filter = ObjectFilter.new()
|
289
|
+
end
|
290
|
+
|
291
|
+
option_to_filter_path = {
|
292
|
+
:name => "publicImages.name",
|
293
|
+
:global_id => "publicImages.globalIdentifier",
|
294
|
+
}
|
295
|
+
|
296
|
+
# For each of the options in the option_to_filter_path map, if the options hash includes
|
297
|
+
# that particular option, add a clause to the object filter that filters for the matching
|
298
|
+
# value
|
299
|
+
option_to_filter_path.each do |option, filter_path|
|
300
|
+
object_filter.modify { |filter| filter.accept(filter_path).when_it is(options_hash[option])} if options_hash[option]
|
301
|
+
end
|
302
|
+
|
303
|
+
# Tags get a much more complex object filter operation so we handle them separately
|
304
|
+
if options_hash.has_key?(:tags)
|
305
|
+
object_filter.set_criteria_for_key_path("publicImages.tagReferences.tag.name", {
|
306
|
+
'operation' => 'in',
|
307
|
+
'options' => [{
|
308
|
+
'name' => 'data',
|
309
|
+
'value' => options_hash[:tags].collect{ |tag_value| tag_value.to_s }
|
310
|
+
}]
|
311
|
+
} );
|
312
|
+
end
|
313
|
+
|
314
|
+
template_service = softlayer_client['Virtual_Guest_Block_Device_Template_Group']
|
315
|
+
template_service = template_service.object_filter(object_filter) unless object_filter.empty?
|
316
|
+
template_service = template_service.object_mask(default_object_mask)
|
317
|
+
|
318
|
+
if options_hash.has_key? :object_mask
|
319
|
+
template_service = template_service.object_mask(options_hash[:object_mask])
|
320
|
+
end
|
321
|
+
|
322
|
+
if options_hash.has_key?(:result_limit)
|
323
|
+
offset = options[:result_limit][:offset]
|
324
|
+
limit = options[:result_limit][:limit]
|
325
|
+
|
326
|
+
template_service = template_service.result_limit(offset, limit)
|
327
|
+
end
|
328
|
+
|
329
|
+
templates_data = template_service.getPublicImages
|
330
|
+
templates_data.collect { |template_data| new(softlayer_client, template_data) }
|
331
|
+
end
|
332
|
+
|
333
|
+
##
|
334
|
+
# Retrive the Image Template with the given ID
|
335
|
+
# (Note! This is the service ID, not the globalIdentifier!)
|
336
|
+
#
|
337
|
+
# The options parameter should contain:
|
338
|
+
#
|
339
|
+
# <b>+:client+</b> - The client used to connect to the API
|
340
|
+
#
|
341
|
+
# If no client is given, then the routine will try to use Client.default_client
|
342
|
+
# If no client can be found the routine will raise an error.
|
343
|
+
#
|
344
|
+
# The options may include the following keys
|
345
|
+
# * <b>+:object_mask+</b> (string) - A object mask of properties, in addition to the default properties, that you wish to retrieve for the template
|
346
|
+
def self.template_with_id(id, options_hash = {})
|
347
|
+
softlayer_client = options_hash[:client] || Client.default_client
|
348
|
+
raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !softlayer_client
|
349
|
+
|
350
|
+
service = softlayer_client['Virtual_Guest_Block_Device_Template_Group'].object_with_id(id)
|
351
|
+
service.object_mask(default_object_mask)
|
352
|
+
|
353
|
+
if options_hash.has_key? :object_mask
|
354
|
+
service = service.object_mask(options_hash[:object_mask])
|
355
|
+
end
|
356
|
+
|
357
|
+
template_data = service.getObject
|
358
|
+
new(softlayer_client, template_data)
|
359
|
+
end
|
360
|
+
|
361
|
+
##
|
362
|
+
# Retrieve the image template with the given global ID
|
363
|
+
#
|
364
|
+
# The options parameter should contain:
|
365
|
+
#
|
366
|
+
# <b>+:client+</b> - The client used to connect to the API
|
367
|
+
#
|
368
|
+
# If no client is given, then the routine will try to use Client.default_client
|
369
|
+
# If no client can be found the routine will raise an error.
|
370
|
+
#
|
371
|
+
# The options may include the following keys
|
372
|
+
# * <b>+:object_mask+</b> (string) - A object mask of properties, in addition to the default properties, that you wish to retrieve for the template
|
373
|
+
def self.template_with_global_id(global_id, options_hash = {})
|
374
|
+
templates = find_public_templates(options_hash.merge(:global_id => global_id))
|
375
|
+
templates.empty? ? nil : templates[0]
|
376
|
+
end
|
377
|
+
|
378
|
+
protected
|
379
|
+
|
380
|
+
def self.default_object_mask
|
381
|
+
return "mask[id,accountId,name,note,globalIdentifier,datacenters,blockDevices,tagReferences,publicFlag,flexImageFlag,transactionId,children.transactionId]"
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|