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.
- checksums.yaml +4 -4
- data/examples/order_virtual_server.rb +1 -1
- data/lib/softlayer/Account.rb +85 -13
- data/lib/softlayer/AccountPassword.rb +356 -0
- data/lib/softlayer/BareMetalServer.rb +21 -13
- data/lib/softlayer/BareMetalServerOrder_Package.rb +30 -13
- data/lib/softlayer/Config.rb +6 -1
- data/lib/softlayer/ImageTemplate.rb +15 -5
- data/lib/softlayer/NetworkMessageDelivery.rb +130 -0
- data/lib/softlayer/NetworkService.rb +95 -0
- data/lib/softlayer/NetworkStorage.rb +340 -0
- data/lib/softlayer/NetworkStorageAllowedHost.rb +77 -0
- data/lib/softlayer/NetworkStorageCredential.rb +204 -0
- data/lib/softlayer/NetworkStorageGroup.rb +159 -0
- data/lib/softlayer/ProductItemCategory.rb +16 -11
- data/lib/softlayer/ProductPackage.rb +7 -2
- data/lib/softlayer/Server.rb +14 -0
- data/lib/softlayer/Service.rb +3 -17
- data/lib/softlayer/Software.rb +368 -0
- data/lib/softlayer/SoftwarePassword.rb +612 -0
- data/lib/softlayer/UserCustomer.rb +144 -0
- data/lib/softlayer/UserCustomerExternalBinding.rb +97 -0
- data/lib/softlayer/VirtualDiskImage.rb +181 -0
- data/lib/softlayer/VirtualDiskImageSoftware.rb +51 -0
- data/lib/softlayer/VirtualServer.rb +2 -2
- data/lib/softlayer/VirtualServerOrder_Package.rb +161 -0
- data/lib/softlayer/base.rb +1 -1
- data/lib/softlayer_api.rb +14 -0
- metadata +33 -19
@@ -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.
|
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
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
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
|
-
#
|
65
|
-
#
|
66
|
-
attr_accessor :
|
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'
|
120
|
-
'
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
132
|
+
'packageId' => @package.id,
|
133
|
+
'hardware' => [{
|
134
|
+
'domain' => @domain,
|
135
|
+
'hostname' => @hostname
|
136
|
+
}],
|
137
|
+
'useHourlyPricing' => !!@hourly
|
125
138
|
}
|
126
139
|
|
127
|
-
|
128
|
-
|
129
|
-
product_order['
|
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
|
data/lib/softlayer/Config.rb
CHANGED
@@ -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
|
-
|
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 => "
|
293
|
-
:global_id => "
|
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("
|
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
|