softlayer_api 2.2.2 → 3.0.b1
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.
- 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
|