softlayer_api 3.0.0 → 3.0.1
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/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
|