softlayer_api 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -50,10 +50,17 @@ module SoftLayer
50
50
  softlayer_client[:Ticket].createCancelServerTicket(self.id, cancel_reason, comment, true, 'HARDWARE')
51
51
  else
52
52
  # Note that reason and comment are ignored in this case, unfortunately
53
- softlayer_client[:Billing_Item].object_with_id(self.billingItem['id'].to_i).cancelService()
53
+ softlayer_client[:Billing_Item].object_with_id(self.service.object_mask("mask[id]").getBillingItem['id'].to_i).cancelService()
54
54
  end
55
55
  end
56
56
 
57
+ ##
58
+ # Returns the username/password combinations for remote management accounts
59
+ #
60
+ def remote_management_accounts
61
+ self['remoteManagementAccounts']
62
+ end
63
+
57
64
  ##
58
65
  # Returns the typical Service used to work with this Server
59
66
  # For Bare Metal Servers that is +SoftLayer_Hardware+ though in some special cases
@@ -69,17 +76,18 @@ module SoftLayer
69
76
  def self.default_object_mask
70
77
  sub_mask = {
71
78
  "mask(SoftLayer_Hardware_Server)" => [
72
- 'bareMetalInstanceFlag',
73
- 'provisionDate',
74
- 'hardwareStatus',
75
- 'memoryCapacity',
76
- 'processorPhysicalCoreAmount',
77
- 'networkManagementIpAddress',
78
- 'networkComponents[id, status, speed, maxSpeed, name, ipmiMacAddress, ipmiIpAddress, macAddress, primaryIpAddress, port, primarySubnet]',
79
- 'activeTransaction[id, transactionStatus[friendlyName,name]]',
80
- 'hardwareChassis[id, name]'
81
- ]
82
- }
79
+ 'activeTransaction[id, transactionStatus[friendlyName,name]]',
80
+ 'bareMetalInstanceFlag',
81
+ 'hardwareChassis[id, name]',
82
+ 'hardwareStatus',
83
+ 'memoryCapacity',
84
+ 'networkComponents[id, maxSpeed, name, ipmiIpAddress, ipmiMacAddress, macAddress, port, primaryIpAddress, primarySubnet, speed, status]',
85
+ 'networkManagementIpAddress',
86
+ 'processorPhysicalCoreAmount',
87
+ 'provisionDate',
88
+ 'remoteManagementAccounts[password,username]'
89
+ ]
90
+ }
83
91
 
84
92
  super.merge(sub_mask)
85
93
  end
@@ -249,4 +257,4 @@ module SoftLayer
249
257
  bare_metal_data.collect { |server_data| BareMetalServer.new(softlayer_client, server_data) }
250
258
  end
251
259
  end #BareMetalServer
252
- end
260
+ end
@@ -56,14 +56,27 @@ module SoftLayer
56
56
  # The following properties are optional, but allow further fine tuning of
57
57
  # the server
58
58
 
59
+ # Boolean, If true, an hourly server will be ordered, otherwise a monthly server will be ordered
60
+ # Corresponds to +useHourlyPricing+ in the SoftLayer_Container_Product_Order_Hardware_Server container
61
+ # documentation
62
+ attr_accessor :hourly
63
+
64
+ # An instance of the SoftLayer::ImageTemplate class. Represents the image template that should
65
+ # be installed on the server.
66
+ attr_accessor :image_template
67
+
68
+ # The URI of a script to execute on the server after it has been provisioned. This may be
69
+ # any object which accepts the to_s message. The resulting string will be passed to SoftLayer API.
70
+ attr_accessor :provision_script_URI
71
+
59
72
  # An array of the ids of SSH keys to install on the server upon provisioning
60
73
  # To obtain a list of existing SSH keys, call getSshKeys on the SoftLayer_Account service:
61
74
  # client[:Account].getSshKeys()
62
75
  attr_accessor :ssh_key_ids
63
76
 
64
- # The URI of a script to execute on the server after it has been provisioned. This may be
65
- # any object which accepts the to_s message. The resulting string will be passed to SoftLayer API.
66
- attr_accessor :provision_script_URI
77
+ # String, User metadata associated with the instance
78
+ # Corresponds to +userData+ in the +SoftLayer_Hardware_Server+ documentation
79
+ attr_accessor :user_metadata
67
80
 
68
81
  ##
69
82
  # You initialize a BareMetalServerOrder_Package by passing in the package that you
@@ -116,17 +129,21 @@ module SoftLayer
116
129
  # based on the configuration options given.
117
130
  def hardware_order
118
131
  product_order = {
119
- 'packageId' => @package.id,
120
- 'useHourlyPricing' => false,
121
- 'hardware' => [{
122
- 'hostname' => @hostname,
123
- 'domain' => @domain
124
- }]
132
+ 'packageId' => @package.id,
133
+ 'hardware' => [{
134
+ 'domain' => @domain,
135
+ 'hostname' => @hostname
136
+ }],
137
+ 'useHourlyPricing' => !!@hourly
125
138
  }
126
139
 
127
- product_order['location'] = @datacenter.id if @datacenter
128
- product_order['sshKeys'] = [{ 'sshKeyIds' => @ssh_key_ids }] if @ssh_key_ids
129
- product_order['provisionScripts'] = [@provision_script_URI.to_s] if @provision_script_URI
140
+ #Note that the use of image_template and SoftLayer::ProductPackage os/guest_diskX configuration category
141
+ #item prices is mutually exclusive.
142
+ product_order['hardware'][0]['userData'] = @user_metadata if @user_metadata
143
+ product_order['imageTemplateGlobalIdentifier'] = @image_template.global_id if @image_template
144
+ product_order['location'] = @datacenter.id if @datacenter
145
+ product_order['provisionScripts'] = [@provision_script_URI.to_s] if @provision_script_URI
146
+ product_order['sshKeys'] = [{ 'sshKeyIds' => @ssh_key_ids }] if @ssh_key_ids
130
147
 
131
148
  product_order['prices'] = @configuration_options.collect do |key, value|
132
149
  if value.respond_to?(:price_id)
@@ -141,4 +158,4 @@ module SoftLayer
141
158
  product_order
142
159
  end
143
160
  end # BareMetalServerOrder_Package
144
- end # SoftLayer
161
+ end # SoftLayer
@@ -95,7 +95,12 @@ module SoftLayer
95
95
  result[:username] = softlayer_section['username'] if softlayer_section['username']
96
96
  result[:endpoint_url] = softlayer_section['endpoint_url'] if softlayer_section['endpoint_url']
97
97
  result[:api_key] = softlayer_section['api_key'] if softlayer_section['api_key']
98
- result[:timeout] = softlayer_section['timeout'] if softlayer_section['timeout']
98
+
99
+ begin
100
+ result[:timeout] = Integer(softlayer_section['timeout']) if softlayer_section['timeout']
101
+ rescue => integer_parse_exception
102
+ $stderr.puts "Expected the value of the timeout configuration property, '#{result[:timeout]}', to be parseable as an integer"
103
+ end
99
104
  end
100
105
  end
101
106
  end
@@ -289,8 +289,8 @@ module SoftLayer
289
289
  end
290
290
 
291
291
  option_to_filter_path = {
292
- :name => "publicImages.name",
293
- :global_id => "publicImages.globalIdentifier",
292
+ :name => "name",
293
+ :global_id => "globalIdentifier",
294
294
  }
295
295
 
296
296
  # For each of the options in the option_to_filter_path map, if the options hash includes
@@ -299,10 +299,10 @@ module SoftLayer
299
299
  option_to_filter_path.each do |option, filter_path|
300
300
  object_filter.modify { |filter| filter.accept(filter_path).when_it is(options_hash[option])} if options_hash[option]
301
301
  end
302
-
302
+
303
303
  # Tags get a much more complex object filter operation so we handle them separately
304
304
  if options_hash.has_key?(:tags)
305
- object_filter.set_criteria_for_key_path("publicImages.tagReferences.tag.name", {
305
+ object_filter.set_criteria_for_key_path("tagReferences.tag.name", {
306
306
  'operation' => 'in',
307
307
  'options' => [{
308
308
  'name' => 'data',
@@ -359,7 +359,12 @@ module SoftLayer
359
359
  end
360
360
 
361
361
  ##
362
- # Retrieve the image template with the given global ID
362
+ # Retrieve the image template with the given global ID. The routine searches the public image template list first
363
+ # and the private image template list if no public image with the given id is found. If no template is found
364
+ # after searching both lists, then the function returns nil.
365
+ #
366
+ # Should either search return more than one result (meaning the system found more than one template with the same
367
+ # global_id), then the routine will throw an exception.
363
368
  #
364
369
  # The options parameter should contain:
365
370
  #
@@ -370,8 +375,13 @@ module SoftLayer
370
375
  #
371
376
  # The options may include the following keys
372
377
  # * <b>+:object_mask+</b> (string) - A object mask of properties, in addition to the default properties, that you wish to retrieve for the template
378
+ #
373
379
  def self.template_with_global_id(global_id, options_hash = {})
374
380
  templates = find_public_templates(options_hash.merge(:global_id => global_id))
381
+ if templates.empty? then
382
+ templates = find_private_templates(options_hash.merge(:global_id => global_id))
383
+ end
384
+ raise "ImageTemplate::template_with_global_id returned more than one template with the same global id. This should not happen" if templates != nil && templates.count > 1
375
385
  templates.empty? ? nil : templates[0]
376
386
  end
377
387
 
@@ -0,0 +1,130 @@
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
+ # Each SoftLayer NetworkMessageDelivery instance provides information about
10
+ # the username/password combination for a specific Network Message Delivery
11
+ # account.
12
+ #
13
+ # This class roughly corresponds to the entity SoftLayer_Network_Message_Delivery
14
+ # in the API.
15
+ #
16
+ class NetworkMessageDelivery < ModelBase
17
+ include ::SoftLayer::DynamicAttribute
18
+
19
+ ##
20
+ # :attr_reader:
21
+ # The date this username/password pair was created.
22
+ sl_attr :created, 'createDate'
23
+
24
+ ##
25
+ # :attr_reader:
26
+ # The date of the last modification to this username/password pair.
27
+ sl_attr :modified, 'modifyDate'
28
+
29
+ ##
30
+ # :attr_reader:
31
+ # The password part of the username/password pair.
32
+ sl_attr :password
33
+
34
+ ##
35
+ # :attr_reader:
36
+ # The username part of the username/password pair.
37
+ sl_attr :username
38
+
39
+ ##
40
+ # The message delivery type description of a network message delivery account.
41
+ sl_dynamic_attr :description do |resource|
42
+ resource.should_update? do
43
+ #only retrieved once per instance
44
+ @description == nil
45
+ end
46
+
47
+ resource.to_update do
48
+ type = self.service.getType
49
+ type['description']
50
+ end
51
+ end
52
+
53
+ ##
54
+ # The message delivery type name of a network message delivery account.
55
+ sl_dynamic_attr :name do |resource|
56
+ resource.should_update? do
57
+ #only retrieved once per instance
58
+ @name == nil
59
+ end
60
+
61
+ resource.to_update do
62
+ type = self.service.getType
63
+ type['name']
64
+ end
65
+ end
66
+
67
+ ##
68
+ # The vendor name for a network message delivery account.
69
+ sl_dynamic_attr :vendor do |resource|
70
+ resource.should_update? do
71
+ #only retrieved once per instance
72
+ @vendor == nil
73
+ end
74
+
75
+ resource.to_update do
76
+ vendor = self.service.getVendor
77
+ vendor['name']
78
+ end
79
+ end
80
+
81
+ ##
82
+ # Updates the password for the current account password.
83
+ #
84
+ def password=(password)
85
+ raise ArgumentError, "The new password cannot be nil" unless password
86
+ raise ArgumentError, "The new password cannot be empty" if password.empty?
87
+
88
+ self.service.editObject({ "password" => password.to_s })
89
+ self.refresh_details()
90
+ end
91
+
92
+ ##
93
+ # Returns the service for interacting with the network message delivery instance
94
+ # through the network API
95
+ #
96
+ def service
97
+ softlayer_client[:Network_Message_Delivery].object_with_id(self.id)
98
+ end
99
+
100
+ ##
101
+ # Make an API request to SoftLayer and return the latest properties hash
102
+ # for this object.
103
+ #
104
+ def softlayer_properties(object_mask = nil)
105
+ my_service = self.service
106
+
107
+ if(object_mask)
108
+ my_service = my_service.object_mask(object_mask)
109
+ else
110
+ my_service = my_service.object_mask(self.class.default_object_mask)
111
+ end
112
+
113
+ my_service.getObject()
114
+ end
115
+
116
+ protected
117
+
118
+ def self.default_object_mask
119
+ {
120
+ "mask(SoftLayer_Network_Message_Delivery)" => [
121
+ 'createDate',
122
+ 'id',
123
+ 'modifyDate',
124
+ 'password',
125
+ 'username'
126
+ ]
127
+ }.to_sl_object_mask
128
+ end
129
+ end
130
+ end #SoftLayer
@@ -0,0 +1,95 @@
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
+ # Each SoftLayer NetworkService instance provides connectivity
10
+ # information for a specific Network Service Resource.
11
+ #
12
+ # This class roughly corresponds to the entity SoftLayer_Network_Service_Resource
13
+ # in the API.
14
+ #
15
+ class NetworkService < ModelBase
16
+ include ::SoftLayer::DynamicAttribute
17
+
18
+ ##
19
+ # :attr_reader:
20
+ # The name associated with this resource
21
+ sl_attr :name
22
+
23
+ ##
24
+ # :attr_reader:
25
+ # The backend IP address for this resource
26
+ sl_attr :private_ip, 'backendIpAddress'
27
+
28
+ ##
29
+ # :attr_reader:
30
+ # The frontend IP address for this resource
31
+ sl_attr :public_ip, 'frontendIpAddress'
32
+
33
+ ##
34
+ # :attr_reader:
35
+ # The ssh username of for this resource
36
+ sl_attr :ssh_username, 'sshUsername'
37
+
38
+ ##
39
+ # Returns the datacenter that this network service resource is available in
40
+ sl_dynamic_attr :datacenter do |resource|
41
+ resource.should_update? do
42
+ #only retrieved once per instance
43
+ @datacenter == nil
44
+ end
45
+
46
+ resource.to_update do
47
+ Datacenter::datacenter_named(self['datacenter']['name'], self.softlayer_client)
48
+ end
49
+ end
50
+
51
+ ##
52
+ # Returns the api properties used to connect to the network service resource
53
+ #
54
+ def api
55
+ {
56
+ 'host' => self['apiHost'],
57
+ 'password' => self['apiPassword'],
58
+ 'path' => self['apiPath'],
59
+ 'port' => self['apiPort'],
60
+ 'protocol' => self['apiProtocol'],
61
+ 'username' => self['apiUsername']
62
+ }
63
+ end
64
+
65
+ ##
66
+ # Returns the network service resource type name
67
+ #
68
+ def type
69
+ self['type']['type']
70
+ end
71
+
72
+ protected
73
+
74
+ def self.default_object_mask
75
+ {
76
+ "mask(SoftLayer_Network_Service_Resource)" => [
77
+ 'apiHost',
78
+ 'apiPassword',
79
+ 'apiPath',
80
+ 'apiPort',
81
+ 'apiProtocol',
82
+ 'apiUsername',
83
+ 'backendIpAddress',
84
+ 'datacenter',
85
+ 'frontendIpAddress',
86
+ 'id',
87
+ 'name',
88
+ 'networkDevice.id',
89
+ 'sshUsername',
90
+ 'type.type'
91
+ ]
92
+ }.to_sl_object_mask
93
+ end
94
+ end
95
+ end #SoftLayer
@@ -0,0 +1,340 @@
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
+ # Each SoftLayer NetworkStorage instance provides information about
10
+ # a storage product and access credentials.
11
+ #
12
+ # This class roughly corresponds to the entity SoftLayer_Network_Storage
13
+ # in the API.
14
+ #
15
+ class NetworkStorage < ModelBase
16
+ include ::SoftLayer::DynamicAttribute
17
+
18
+ ##
19
+ # :attr_reader:
20
+ # A Storage account's capacity, measured in gigabytes.
21
+ sl_attr :capacity, 'capacityGb'
22
+
23
+ ##
24
+ # :attr_reader:
25
+ # The date a network storage volume was created.
26
+ sl_attr :created, 'createDate'
27
+
28
+ ##
29
+ # :attr_reader:
30
+ # Public notes related to a Storage volume.
31
+ sl_attr :notes
32
+
33
+ ##
34
+ # :attr_reader:
35
+ # The password used to access a non-EVault Storage volume.
36
+ # This password is used to register the EVault server agent with the
37
+ # vault backup system.
38
+ sl_attr :password
39
+
40
+ ##
41
+ # :attr_reader:
42
+ # A Storage account's type.
43
+ sl_attr :type, 'nasType'
44
+
45
+ ##
46
+ # :attr_reader:
47
+ # This flag indicates whether this storage type is upgradable or not.
48
+ sl_attr :upgradable, 'upgradableFlag'
49
+
50
+ ##
51
+ # :attr_reader:
52
+ # The username used to access a non-EVault Storage volume.
53
+ # This username is used to register the EVault server agent with the
54
+ # vault backup system.
55
+ sl_attr :username
56
+
57
+ ##
58
+ # Other usernames and passwords associated with a Storage volume.
59
+ sl_dynamic_attr :account_password do |resource|
60
+ resource.should_update? do
61
+ #only retrieved once per instance
62
+ @account_password == nil
63
+ end
64
+
65
+ resource.to_update do
66
+ account_password = self.service.object_mask(AccountPassword.default_object_mask).getAccountPassword
67
+ AccountPassword.new(softlayer_client, account_password) unless account_password.empty?
68
+ end
69
+ end
70
+
71
+ ##
72
+ # A Storage volume's access credentials.
73
+ sl_dynamic_attr :credentials do |resource|
74
+ resource.should_update? do
75
+ #only retrieved once per instance
76
+ @credentials == nil
77
+ end
78
+
79
+ resource.to_update do
80
+ self.service.object_mask(NetworkStorageCredential.default_object_mask).getCredentials.collect{|cred| NetworkStorageCredential.new(softlayer_client, cred) }
81
+ end
82
+ end
83
+
84
+ ##
85
+ # The network resource a Storage service is connected to.
86
+ sl_dynamic_attr :service_resource do |resource|
87
+ resource.should_update? do
88
+ #only retrieved once per instance
89
+ @service_resource == nil
90
+ end
91
+
92
+ resource.to_update do
93
+ NetworkService.new(softlayer_client, self.service.object_mask(NetworkService.default_object_mask).getServiceResource)
94
+ end
95
+ end
96
+
97
+ ##
98
+ # The account username and password for the EVault webCC interface.
99
+ sl_dynamic_attr :webcc_account do |resource|
100
+ resource.should_update? do
101
+ #only retrieved once per instance
102
+ @webcc_account == nil
103
+ end
104
+
105
+ resource.to_update do
106
+ webcc_account = self.service.object_mask(AccountPassword.default_object_mask).getWebccAccount
107
+ AccountPassword.new(softlayer_client, webcc_account) unless webcc_account.empty?
108
+ end
109
+ end
110
+
111
+ ##
112
+ # Add a username/password credential to the network storage instance
113
+ #
114
+ def add_credential(credential_type)
115
+ raise ArgumentError, "The new credential type cannot be nil" unless credential_type
116
+ raise ArgumentError, "The new credential type cannot be empty" if credential_type.empty?
117
+
118
+ new_credential = self.service.object_mask(NetworkStorageCredential.default_object_mask).assignNewCredential(credential_type.to_s)
119
+
120
+ @credentials = nil
121
+
122
+ NetworkStorageCredential.new(softlayer_client, new_credential) unless new_credential.empty?
123
+ end
124
+
125
+ ##
126
+ # Assign an existing network storage credential specified by the username to the network storage instance
127
+ #
128
+ def assign_credential(username)
129
+ raise ArgumentError, "The username cannot be nil" unless username
130
+ raise ArgumentError, "The username cannot be empty" if username.empty?
131
+
132
+ self.service.assignCredential(username.to_s)
133
+
134
+ @credentials = nil
135
+ end
136
+
137
+ ##
138
+ # Determines if one of the credentials pertains to the specified username.
139
+ #
140
+ def has_user_credential?(username)
141
+ self.credentials.map { |credential| credential.username }.include?(username)
142
+ end
143
+
144
+ ##
145
+ # Updates the notes for the network storage instance.
146
+ #
147
+ def notes=(notes)
148
+ self.service.editObject({ "notes" => notes.to_s })
149
+ self.refresh_details()
150
+ end
151
+
152
+ ##
153
+ # Updates the password for the network storage instance.
154
+ #
155
+ def password=(password)
156
+ raise ArgumentError, "The new password cannot be nil" unless password
157
+ raise ArgumentError, "The new password cannot be empty" if password.empty?
158
+
159
+ self.service.editObject({ "password" => password.to_s })
160
+ self.refresh_details()
161
+ end
162
+
163
+ ##
164
+ # Remove an existing network storage credential specified by the username from the network storage instance
165
+ #
166
+ def remove_credential(username)
167
+ raise ArgumentError, "The username cannot be nil" unless username
168
+ raise ArgumentError, "The username cannot be empty" if username.empty?
169
+
170
+ self.service.removeCredential(username.to_s)
171
+
172
+ @credentials = nil
173
+ end
174
+
175
+ ##
176
+ # Retrieve a list of network storage services.
177
+ #
178
+ # The options parameter should contain:
179
+ #
180
+ # <b>+:client+</b> - The client used to connect to the API
181
+ #
182
+ # If no client is given, then the routine will try to use Client.default_client
183
+ # If no client can be found the routine will raise an error.
184
+ #
185
+ # You may filter the list returned by adding options:
186
+ # * <b>+:datacenter+</b> (string) - Include network storage associated with servers matching this datacenter
187
+ # * <b>+:domain+</b> (string) - Include network storage associated with servers matching this domain
188
+ # * <b>+:hostname+</b> (string) - Include network storage associated with servers matching this hostname
189
+ # * <b>+:network_storage_server_type+</b> (string) - Include network storage associated with this server type
190
+ # * <b>+:network_storage_type+</b> (string) - Include network storage from devices of this storage type
191
+ # * <b>+:service+</b> (string) - Include network storage from devices with this service fqdn
192
+ # * <b>+:tags+</b> (Array) - Include network storage associated with servers matching these tags
193
+ #
194
+ def self.find_network_storage(options_hash = {})
195
+ softlayer_client = options_hash[:client] || Client.default_client
196
+ raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !softlayer_client
197
+
198
+ if(options_hash.has_key? :network_storage_object_filter)
199
+ network_storage_object_filter = options_hash[:network_storage_object_filter]
200
+ raise "Expected an instance of SoftLayer::ObjectFilter" unless network_storage_object_filter.kind_of?(SoftLayer::ObjectFilter)
201
+ else
202
+ network_storage_object_filter = ObjectFilter.new()
203
+ end
204
+
205
+ if options_hash.has_key?(:network_storage_server_type) && ! [ :hardware, :virtual_server ].include?(options_hash[:network_storage_server_type])
206
+ raise "Expected one of :hardware or :virtual_server for :network_storage_server_type option in #{__method__}"
207
+ end
208
+
209
+ filter_label = {
210
+ :evault => "evaultNetworkStorage",
211
+ :hardware => "hardware",
212
+ :hub => "hubNetworkStorage",
213
+ :iscsi => "iscsiNetworkStorage",
214
+ :lockbox => "lockboxNetworkStorage",
215
+ :nas => "nasNetworkStorage",
216
+ :network_storage => "networkStorage",
217
+ :virtual_server => "virtualGuest"
218
+ }
219
+
220
+ option_to_filter_path = {
221
+ :datacenter => lambda { |storage_type, server_type| return [ filter_label[storage_type], '.', filter_label[server_type], '.datacenter.name' ].join },
222
+ :domain => lambda { |storage_type, server_type| return [ filter_label[storage_type], '.', filter_label[server_type], '.domain' ].join },
223
+ :hostname => lambda { |storage_type, server_type| return [ filter_label[storage_type], '.', filter_label[server_type], '.hostname' ].join },
224
+ :service => lambda { |storage_type| return [ filter_label[storage_type], '.serviceResource.backendIpAddress' ].join },
225
+ :tags => lambda { |storage_type, server_type| return [ filter_label[storage_type], '.', filter_label[server_type], '.tagReferences.tag.name' ].join },
226
+ }
227
+
228
+ if options_hash[:network_storage_type]
229
+ unless filter_label.select{|label,filter| filter.end_with?("Storage")}.keys.include?(options_hash[:network_storage_type])
230
+ raise "Expected :evault, :hub, :iscsi, :lockbox, :nas or :network_storage for option :network_storage_type in #{__method__}"
231
+ end
232
+ end
233
+
234
+ network_storage_type = options_hash[:network_storage_type] || :network_storage
235
+
236
+ if options_hash[:service]
237
+ network_storage_object_filter.modify do |filter|
238
+ filter.accept(option_to_filter_path[:service].call(network_storage_type)).when_it is(options_hash[:service])
239
+ end
240
+ end
241
+
242
+ if options_hash[:network_storage_server_type]
243
+ [ :datacenter, :domain, :hostname ].each do |option|
244
+ if options_hash[option]
245
+ network_storage_object_filter.modify do |filter|
246
+ filter.accept(option_to_filter_path[option].call(network_storage_type, options_hash[:network_storage_server_type])).when_it is(options_hash[option])
247
+ end
248
+ end
249
+ end
250
+
251
+ if options_hash[:tags]
252
+ network_storage_object_filter.set_criteria_for_key_path(option_to_filter_path[:tags].call(network_storage_type, options_hash[:network_storage_server_type]),
253
+ {
254
+ 'operation' => 'in',
255
+ 'options' => [{
256
+ 'name' => 'data',
257
+ 'value' => options_hash[:tags].collect{ |tag_value| tag_value.to_s }
258
+ }]
259
+ })
260
+ end
261
+ end
262
+
263
+ account_service = softlayer_client[:Account]
264
+ account_service = account_service.object_filter(network_storage_object_filter) unless network_storage_object_filter.empty?
265
+ account_service = account_service.object_mask(NetworkStorage.default_object_mask)
266
+ account_service = account_service.object_mask(options_hash[:network_storage_object_mask]) if options_hash[:network_storage_object_mask]
267
+
268
+ case options_hash[:network_storage_type]
269
+ when :evault
270
+ network_storage_data = account_service.getEvaultNetworkStorage
271
+ when :hub
272
+ network_storage_data = account_service.getHubNetworkStorage
273
+ when :iscsi
274
+ network_storage_data = account_service.getIscsiNetworkStorage
275
+ when :lockbox
276
+ network_storage_data = account_service.getLockboxNetworkStorage
277
+ when :nas
278
+ network_storage_data = account_service.getNasNetworkStorage
279
+ when :network_storage, nil
280
+ network_storage_data = account_service.getNetworkStorage
281
+ end
282
+
283
+ network_storage_data.collect { |network_storage| NetworkStorage.new(softlayer_client, network_storage) unless network_storage.empty? }.compact
284
+ end
285
+
286
+ ##
287
+ # Returns the service for interacting with this network storage through the network API
288
+ #
289
+ def service
290
+ softlayer_client[:Network_Storage].object_with_id(self.id)
291
+ end
292
+
293
+ ##
294
+ # Make an API request to SoftLayer and return the latest properties hash
295
+ # for this object.
296
+ #
297
+ def softlayer_properties(object_mask = nil)
298
+ my_service = self.service
299
+
300
+ if(object_mask)
301
+ my_service = my_service.object_mask(object_mask)
302
+ else
303
+ my_service = my_service.object_mask(self.class.default_object_mask)
304
+ end
305
+
306
+ my_service.getObject()
307
+ end
308
+
309
+ ##
310
+ # Updates the password for the network storage credential of the username specified.
311
+ #
312
+ def update_credential_password(username, password)
313
+ raise ArgumentError, "The new password cannot be nil" unless password
314
+ raise ArgumentError, "The new username cannot be nil" unless username
315
+ raise ArgumentError, "The new password cannot be empty" if password.empty?
316
+ raise ArgumentError, "The new username cannot be empty" if username.empty?
317
+
318
+ self.service.editCredential(username.to_s, password.to_s)
319
+
320
+ @credentials = nil
321
+ end
322
+
323
+ protected
324
+
325
+ def self.default_object_mask
326
+ {
327
+ "mask(SoftLayer_Network_Storage)" => [
328
+ 'capacityGb',
329
+ 'createDate',
330
+ 'id',
331
+ 'nasType',
332
+ 'notes',
333
+ 'password',
334
+ 'upgradableFlag',
335
+ 'username'
336
+ ]
337
+ }.to_sl_object_mask
338
+ end
339
+ end
340
+ end #SoftLayer