softlayer_api 3.0.2 → 3.1.0

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.textile +3 -0
  3. data/lib/softlayer/Account.rb +85 -8
  4. data/lib/softlayer/AccountPassword.rb +49 -49
  5. data/lib/softlayer/BareMetalServer.rb +33 -43
  6. data/lib/softlayer/BareMetalServerOrder.rb +17 -8
  7. data/lib/softlayer/BareMetalServerOrder_Package.rb +25 -7
  8. data/lib/softlayer/Client.rb +7 -7
  9. data/lib/softlayer/Config.rb +105 -49
  10. data/lib/softlayer/Datacenter.rb +10 -2
  11. data/lib/softlayer/DynamicAttribute.rb +1 -1
  12. data/lib/softlayer/ImageTemplate.rb +44 -61
  13. data/lib/softlayer/ModelBase.rb +2 -2
  14. data/lib/softlayer/NetworkComponent.rb +25 -3
  15. data/lib/softlayer/NetworkMessageDelivery.rb +25 -5
  16. data/lib/softlayer/NetworkMonitor.rb +333 -0
  17. data/lib/softlayer/NetworkService.rb +6 -4
  18. data/lib/softlayer/NetworkStorage.rb +42 -29
  19. data/lib/softlayer/NetworkStorageAllowedHost.rb +9 -3
  20. data/lib/softlayer/NetworkStorageCredential.rb +44 -29
  21. data/lib/softlayer/NetworkStorageGroup.rb +42 -10
  22. data/lib/softlayer/ObjectFilter.rb +54 -4
  23. data/lib/softlayer/ObjectMaskParser.rb +1 -1
  24. data/lib/softlayer/ProductItemCategory.rb +34 -5
  25. data/lib/softlayer/ProductPackage.rb +11 -7
  26. data/lib/softlayer/Server.rb +77 -5
  27. data/lib/softlayer/ServerFirewall.rb +12 -11
  28. data/lib/softlayer/Service.rb +1 -1
  29. data/lib/softlayer/Software.rb +35 -50
  30. data/lib/softlayer/SoftwarePassword.rb +92 -107
  31. data/lib/softlayer/Ticket.rb +37 -28
  32. data/lib/softlayer/UserCustomer.rb +56 -13
  33. data/lib/softlayer/UserCustomerExternalBinding.rb +18 -5
  34. data/lib/softlayer/VLANFirewall.rb +40 -9
  35. data/lib/softlayer/VLANFirewallOrder.rb +1 -1
  36. data/lib/softlayer/VirtualDiskImage.rb +38 -10
  37. data/lib/softlayer/VirtualServer.rb +75 -48
  38. data/lib/softlayer/VirtualServerOrder.rb +15 -8
  39. data/lib/softlayer/VirtualServerOrder_Package.rb +25 -7
  40. data/lib/softlayer/VirtualServerUpgradeOrder.rb +1 -1
  41. data/lib/softlayer/base.rb +1 -1
  42. data/lib/softlayer/object_mask_helpers.rb +1 -1
  43. data/lib/softlayer_api.rb +2 -0
  44. metadata +4 -3
@@ -78,6 +78,14 @@ module SoftLayer
78
78
  # Object responding to to_s and providing a valid URI, The URI of a post provisioning script to run on
79
79
  # this server once it is created.
80
80
  # Corresponds to +postInstallScriptUri+ in the +createObject+ documentation
81
+ attr_accessor :provision_script_uri
82
+
83
+ # Object responding to to_s and providing a valid URI, The URI of a post provisioning script to run on
84
+ # this server once it is created.
85
+ # Corresponds to +postInstallScriptUri+ in the +createObject+ documentation
86
+ #
87
+ # DEPRECATION WARNING: This attribute is deprecated in favor of provision_script_uri
88
+ # and will be removed in the next major release.
81
89
  attr_accessor :provision_script_URI
82
90
 
83
91
  # Boolean, If true then the server will only have a private network interface (and no public network interface)
@@ -93,7 +101,7 @@ module SoftLayer
93
101
  attr_accessor :max_port_speed
94
102
 
95
103
  ##
96
- # Create a new order that works thorugh the given client connection
104
+ # Create a new order that works through the given client connection
97
105
  def initialize (client = nil)
98
106
  @softlayer_client = client || Client.default_client
99
107
  raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !@softlayer_client
@@ -149,13 +157,14 @@ module SoftLayer
149
157
 
150
158
  template['privateNetworkOnlyFlag'] = true if @private_network_only
151
159
 
152
- template['datacenter'] = {"name" => @datacenter.name} if @datacenter
153
- template['userData'] = [{'value' => @user_metadata}] if @user_metadata
154
- template['networkComponents'] = [{'maxSpeed'=> @max_port_speed}] if @max_port_speed
155
- template['postInstallScriptUri'] = @provision_script_URI.to_s if @provision_script_URI
156
- template['sshKeys'] = @ssh_key_ids.collect { |ssh_key| {'id'=> ssh_key.to_i } } if @ssh_key_ids
157
- template['primaryNetworkComponent'] = { "networkVlan" => { "id" => @public_vlan_id.to_i } } if @public_vlan_id
160
+ template['datacenter'] = {"name" => @datacenter.name} if @datacenter
161
+ template['userData'] = [{'value' => @user_metadata}] if @user_metadata
162
+ template['networkComponents'] = [{'maxSpeed'=> @max_port_speed}] if @max_port_speed
163
+ template['postInstallScriptUri'] = @provision_script_URI.to_s if @provision_script_URI
164
+ template['postInstallScriptUri'] = @provision_script_uri.to_s if @provision_script_uri
165
+ template['primaryNetworkComponent'] = { "networkVlan" => { "id" => @public_vlan_id.to_i } } if @public_vlan_id
158
166
  template['primaryBackendNetworkComponent'] = { "networkVlan" => {"id" => @private_vlan_id.to_i } } if @private_vlan_id
167
+ template['sshKeys'] = @ssh_key_ids.collect { |ssh_key| {'id'=> ssh_key.to_i } } if @ssh_key_ids
159
168
 
160
169
  if @disks && !@disks.empty?
161
170
  template['hardDrives'] = @disks.collect do |disk|
@@ -195,7 +204,7 @@ module SoftLayer
195
204
  end
196
205
 
197
206
  ##
198
- # Returns a list of the valid :os_refrence_codes
207
+ # Returns a list of the valid :os_reference_codes
199
208
  def self.os_reference_code_options(client = nil)
200
209
  create_object_options(client)['operatingSystems'].collect { |os_spec| os_spec['template']['operatingSystemReferenceCode'] }.uniq.sort!
201
210
  end
@@ -42,14 +42,14 @@ module SoftLayer
42
42
  # The domain of the server being created (i.e. 'softlayer.com' is the domain of sldn.softlayer.com)
43
43
  attr_accessor :domain
44
44
 
45
- # The value of this property should be a hash. The keys of the hash are ProdcutItemCategory
45
+ # The value of this property should be a hash. The keys of the hash are ProductItemCategory
46
46
  # codes (like 'os' and 'ram') while the values may be Integers or Objects. The Integer values
47
47
  # should be the +id+ of a +SoftLayer_Product_Item_Price+ representing the configuration option
48
48
  # chosen for that category. Objects must respond to the +price_id+ message and return an integer
49
49
  # that is the +id+ of a +SoftLayer_Product_Item_Price+. Instances of the ProductConfigurationOption
50
50
  # class behave this way.
51
51
  #
52
- # At a minimum, the configuation_options should include entries for each of the categories
52
+ # At a minimum, the configuration_options should include entries for each of the categories
53
53
  # required by the package (i.e. those returned from ProductPackage#required_categories)
54
54
  attr_accessor :configuration_options
55
55
 
@@ -65,8 +65,23 @@ module SoftLayer
65
65
  # be installed on the server.
66
66
  attr_accessor :image_template
67
67
 
68
+ # Integer, The id of the public VLAN this server should join
69
+ # Corresponds to +primaryNetworkComponent.networkVlan.id+ in the +createObject+ documentation
70
+ attr_accessor :public_vlan_id
71
+
72
+ # Integer, The id of the private VLAN this server should join
73
+ # Corresponds to +primaryBackendNetworkComponent.networkVlan.id+ in the +createObject+ documentation
74
+ attr_accessor :private_vlan_id
75
+
76
+ # The URI of a script to execute on the server after it has been provisioned. This may be
77
+ # any object which accepts the to_s message. The resulting string will be passed to SoftLayer API.
78
+ attr_accessor :provision_script_uri
79
+
68
80
  # The URI of a script to execute on the server after it has been provisioned. This may be
69
81
  # any object which accepts the to_s message. The resulting string will be passed to SoftLayer API.
82
+ #
83
+ # DEPRECATION WARNING: This attribute is deprecated in favor of provision_script_uri
84
+ # and will be removed in the next major release.
70
85
  attr_accessor :provision_script_URI
71
86
 
72
87
  # An array of the ids of SSH keys to install on the server upon provisioning
@@ -139,11 +154,14 @@ module SoftLayer
139
154
 
140
155
  #Note that the use of image_template and SoftLayer::ProductPackage os/guest_diskX configuration category
141
156
  #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
157
+ product_order['hardware'][0]['userData'] = @user_metadata if @user_metadata
158
+ product_order['imageTemplateGlobalIdentifier'] = @image_template.global_id if @image_template
159
+ product_order['location'] = @datacenter.id if @datacenter
160
+ product_order['provisionScripts'] = [@provision_script_URI.to_s] if @provision_script_URI
161
+ product_order['provisionScripts'] = [@provision_script_uri.to_s] if @provision_script_uri
162
+ product_order['sshKeys'] = [{ 'sshKeyIds' => @ssh_key_ids }] if @ssh_key_ids
163
+ product_order['primaryNetworkComponent'] = { "networkVlan" => { "id" => @public_vlan_id.to_i } } if @public_vlan_id
164
+ product_order['primaryBackendNetworkComponent'] = { "networkVlan" => {"id" => @private_vlan_id.to_i } } if @private_vlan_id
147
165
 
148
166
  product_order['prices'] = @configuration_options.collect do |key, value|
149
167
  if value.respond_to?(:price_id)
@@ -6,7 +6,7 @@
6
6
 
7
7
  module SoftLayer
8
8
  # A client is responsible for storing authentication information for API calls and
9
- # it serves as a centeral repository for the Service instances that call into the
9
+ # it serves as a central repository for the Service instances that call into the
10
10
  # network API.
11
11
  #
12
12
  # When you create a client, you pass in hash arguments specifying how the client
@@ -21,16 +21,16 @@ module SoftLayer
21
21
  # class to provide the missing information. Please see that class for details.
22
22
  #
23
23
  class Client
24
- # A username passed as authentication for each request. Cannot be emtpy or nil.
24
+ # A username passed as authentication for each request. Cannot be empty or nil.
25
25
  attr_reader :username
26
26
 
27
- # An API key passed as part of the authentication of each request. Cannot be emtpy or nil.
27
+ # An API key passed as part of the authentication of each request. Cannot be empty or nil.
28
28
  attr_reader :api_key
29
29
 
30
- # The base URL for requests that are passed to the server. Cannot be emtpy or nil.
30
+ # The base URL for requests that are passed to the server. Cannot be empty or nil.
31
31
  attr_reader :endpoint_url
32
32
 
33
- # A string passsed as the value for the User-Agent header when requests are sent to SoftLayer API.
33
+ # A string passed as the value for the User-Agent header when requests are sent to SoftLayer API.
34
34
  attr_accessor :user_agent
35
35
 
36
36
  # An integer value (in seconds). The number of seconds to wait for HTTP requests to the network API
@@ -63,7 +63,7 @@ module SoftLayer
63
63
  # Clients are built with a number of settings:
64
64
  # * <b>+:username+</b> - The username of the account you wish to access through the API
65
65
  # * <b>+:api_key+</b> - The API key used to authenticate the user with the API
66
- # * <b>+:enpoint_url+</b> - The API endpoint the client should connect to. This defaults to API_PUBLIC_ENDPOINT
66
+ # * <b>+:endpoint_url+</b> - The API endpoint the client should connect to. This defaults to API_PUBLIC_ENDPOINT
67
67
  # * <b>+:user_agent+</b> - A string that is passed along as the user agent when the client sends requests to the server
68
68
  # * <b>+:timeout+</b> - An integer number of seconds to wait until network requests time out. Corresponds to the network_timeout property of the client
69
69
  #
@@ -92,7 +92,7 @@ module SoftLayer
92
92
 
93
93
  raise "A SoftLayer Client requires a username" if !@username || @username.empty?
94
94
  raise "A SoftLayer Client requires an api_key" if !@api_key || @api_key.empty?
95
- raise "A SoftLayer Clietn requires an enpoint URL" if !@endpoint_url || @endpoint_url.empty?
95
+ raise "A SoftLayer Client requires an endpoint URL" if !@endpoint_url || @endpoint_url.empty?
96
96
  end
97
97
 
98
98
  # return a hash of the authentication headers for the client
@@ -11,7 +11,7 @@ module SoftLayer
11
11
  # The SoftLayer Config class is responsible for providing the key information
12
12
  # the library needs to communicate with the network SoftLayer API. Those three crucial
13
13
  # pieces of information are the Username, the API Key, and the endpoint_url. This information
14
- # is collected in a hash with the keys `:username`, `:api_key`, and `:endpoint_url` repsectively.
14
+ # is collected in a hash with the keys `:username`, `:api_key`, and `:endpoint_url` respectively.
15
15
  #
16
16
  # The routine used to retrieve this information from a Config object is Config.client_settings
17
17
  #
@@ -36,14 +36,16 @@ module SoftLayer
36
36
  # SoftLayer-Python language bindings). A simple config file looks something like this:
37
37
  #
38
38
  # [softlayer]
39
- # username = joeusername
40
39
  # api_key = DEADBEEFBADF00D
40
+ # endpoint_url = 'API_PUBLIC_ENDPOINT'
41
41
  # timeout = 60
42
+ # user_agent = "softlayer-ruby x.x.x"
43
+ # username = joeusername
42
44
  #
43
45
  # = Environment Variables
44
46
  #
45
47
  # The config class will search the environment variables SL_USERNAME and SL_API_KEY for
46
- # the username and API key respectively. The endpoint_url may not be set thorugh
48
+ # the username and API key respectively. The endpoint_url may not be set through
47
49
  # environment variables.
48
50
  #
49
51
  # = Global Variables
@@ -52,7 +54,16 @@ module SoftLayer
52
54
  #
53
55
  # - +$SL_API_USERNAME+
54
56
  # - +$SL_API_KEY+
55
- # - +$SL_API_BASE_URL+
57
+ # - +$SL_API_BASE_URL+ (or alias +$SL_API_ENDPOINT_URL+)
58
+ #
59
+ # = XML RPC Variables
60
+ #
61
+ # The config allows for two variables that are passed on to the underlying XML RPC agent
62
+ # for interacting with the SoftLayer API (as with other settings these can be loaded from
63
+ # config file, environment variables, globals or provided values):
64
+ #
65
+ # - +SL_API_TIMEOUT+
66
+ # - +SL_API_USER_AGENT+
56
67
  #
57
68
  # = Direct parameters
58
69
  #
@@ -60,62 +71,107 @@ module SoftLayer
60
71
  # of the key information is provided in that hash, that information will override
61
72
  # any discovered through the techniques above.
62
73
  #
74
+ class Config
75
+ ENDPOINT_URL_ALIAS = [ 'API_PRIVATE_ENDPOINT', 'API_PUBLIC_ENDPOINT' ]
76
+ FILE_LOCATIONS = [ '/etc/softlayer.conf', '~/.softlayer', './.softlayer' ]
77
+
78
+ def Config.client_settings(provided_settings = {})
79
+ settings = { :endpoint_url => API_PUBLIC_ENDPOINT }
80
+
81
+ settings.merge! file_settings
82
+ settings.merge! environment_settings
83
+ settings.merge! globals_settings
84
+ settings.merge! provided_settings
85
+
86
+ settings
87
+ end
63
88
 
64
- class Config
65
- def Config.globals_settings
66
- result = {}
67
- result[:username] = $SL_API_USERNAME if $SL_API_USERNAME
68
- result[:api_key] = $SL_API_KEY if $SL_API_KEY
69
- result[:endpoint_url] = $SL_API_BASE_URL || API_PUBLIC_ENDPOINT
70
- result
71
- end
89
+ def Config.environment_settings
90
+ result = {}
72
91
 
73
- def Config.environment_settings
74
- result = {}
75
- result[:username] = ENV['SL_USERNAME'] if ENV['SL_USERNAME']
76
- result[:api_key] = ENV['SL_API_KEY'] if ENV['SL_API_KEY']
77
- result
78
- end
92
+ result[:api_key] = ENV['SL_API_KEY'] if ENV['SL_API_KEY']
93
+ result[:user_agent] = ENV['SL_API_USER_AGENT'] || "softlayer_api gem/#{SoftLayer::VERSION} (Ruby #{RUBY_PLATFORM}/#{RUBY_VERSION})"
94
+ result[:username] = ENV['SL_USERNAME'] if ENV['SL_USERNAME']
79
95
 
80
- FILE_LOCATIONS = ['/etc/softlayer.conf', '~/.softlayer', './.softlayer']
96
+ if ENV['SL_API_BASE_URL'] && ENDPOINT_URL_ALIAS.include?(ENV['SL_API_BASE_URL'])
97
+ result[:endpoint_url] = (ENV["SL_API_BASE_URL"] == "API_PUBLIC_ENDPOINT" ? API_PUBLIC_ENDPOINT : API_PRIVATE_ENDPOINT)
98
+ elsif ENV['SL_API_ENDPOINT_URL'] && ENDPOINT_URL_ALIAS.include?(ENV['SL_API_ENDPOINT_URL'])
99
+ result[:endpoint_url] = (ENV["SL_API_ENDPOINT_URL"] == "API_PUBLIC_ENDPOINT" ? API_PUBLIC_ENDPOINT : API_PRIVATE_ENDPOINT)
100
+ elsif (ENV['SL_API_BASE_URL'] && ! ENDPOINT_URL_ALIAS.include?(ENV['SL_API_BASE_URL'])) ||
101
+ (ENV['SL_API_ENDPOINT_URL'] && ! ENDPOINT_URL_ALIAS.include?(ENV['SL_API_ENDPOINT_URL']))
102
+ result[:endpoint_url] = ENV['SL_API_BASE_URL'] || ENV['SL_API_ENDPOINT_URL']
103
+ end
81
104
 
82
- def Config.file_settings(*additional_files)
83
- result = {}
105
+ begin
106
+ result[:timeout] = Integer(ENV['SL_API_TIMEOUT']) if ENV['SL_API_TIMEOUT']
107
+ rescue => integer_parse_exception
108
+ raise "Expected the value of the timeout configuration property, '#{ENV['SL_API_TIMEOUT']}', to be parseable as an integer"
109
+ end
84
110
 
85
- search_path = FILE_LOCATIONS
86
- search_path = search_path + additional_files if additional_files
87
- search_path = search_path.map { |file_path| File.expand_path(file_path) }
111
+ result
112
+ end
88
113
 
89
- search_path.each do |file_path|
90
- if File.readable? file_path
91
- config = ConfigParser.new file_path
92
- softlayer_section = config['softlayer']
114
+ def Config.file_settings(*additional_files)
115
+ result = {}
93
116
 
94
- if softlayer_section
95
- result[:username] = softlayer_section['username'] if softlayer_section['username']
96
- result[:endpoint_url] = softlayer_section['endpoint_url'] if softlayer_section['endpoint_url']
97
- result[:api_key] = softlayer_section['api_key'] if softlayer_section['api_key']
117
+ search_path = FILE_LOCATIONS
118
+ search_path = search_path + additional_files if additional_files
119
+ search_path = search_path.map { |file_path| File.expand_path(file_path) }
120
+
121
+ search_path.each do |file_path|
122
+ if File.readable? file_path
123
+ config = ConfigParser.new file_path
124
+ softlayer_section = config['softlayer']
125
+
126
+ if softlayer_section
127
+ result[:api_key] = softlayer_section['api_key'] if softlayer_section['api_key']
128
+ result[:user_agent] = softlayer_section['user_agent'] || "softlayer_api gem/#{SoftLayer::VERSION} (Ruby #{RUBY_PLATFORM}/#{RUBY_VERSION})"
129
+ result[:username] = softlayer_section['username'] if softlayer_section['username']
130
+
131
+ if softlayer_section['base_url'] && ENDPOINT_URL_ALIAS.include?(softlayer_section['base_url'])
132
+ result[:endpoint_url] = (softlayer_section['base_url'] == "API_PUBLIC_ENDPOINT" ? API_PUBLIC_ENDPOINT : API_PRIVATE_ENDPOINT)
133
+ elsif softlayer_section['endpoint_url'] && ENDPOINT_URL_ALIAS.include?(softlayer_section['endpoint_url'])
134
+ result[:endpoint_url] = (softlayer_section['endpoint_url'] == "API_PUBLIC_ENDPOINT" ? API_PUBLIC_ENDPOINT : API_PRIVATE_ENDPOINT)
135
+ elsif (softlayer_section['base_url'] && ! ENDPOINT_URL_ALIAS.include?(softlayer_section['base_url'])) ||
136
+ (softlayer_section['endpoint_url'] && ! ENDPOINT_URL_ALIAS.include?(softlayer_section['endpoint_url']))
137
+ result[:endpoint_url] = softlayer_section['base_url'] || softlayer_section['endpoint_url']
138
+ end
98
139
 
99
140
  begin
100
- result[:timeout] = Integer(softlayer_section['timeout']) if softlayer_section['timeout']
141
+ result[:timeout] = Integer(softlayer_section['timeout']) if softlayer_section['timeout']
101
142
  rescue => integer_parse_exception
102
- $stderr.puts "Expected the value of the timeout configuration property, '#{result[:timeout]}', to be parseable as an integer"
143
+ raise "Expected the value of the timeout configuration property, '#{softlayer_section['timeout']}', to be parseable as an integer"
103
144
  end
104
- end
105
- end
106
- end
145
+ end
146
+ end
147
+ end
107
148
 
108
- result
109
- end
149
+ result
150
+ end
110
151
 
111
- def Config.client_settings(provided_settings = {})
112
- settings = { :endpoint_url => API_PUBLIC_ENDPOINT }
113
- settings.merge! file_settings
114
- settings.merge! environment_settings
115
- settings.merge! globals_settings
116
- settings.merge! provided_settings
117
-
118
- settings
119
- end
120
- end
152
+ def Config.globals_settings
153
+ result = {}
154
+
155
+ result[:api_key] = $SL_API_KEY if $SL_API_KEY
156
+ result[:user_agent] = $SL_API_USER_AGENT || "softlayer_api gem/#{SoftLayer::VERSION} (Ruby #{RUBY_PLATFORM}/#{RUBY_VERSION})"
157
+ result[:username] = $SL_API_USERNAME if $SL_API_USERNAME
158
+
159
+ if $SL_API_ENDPOINT_URL && ENDPOINT_URL_ALIAS.include?($SL_API_ENDPOINT_URL)
160
+ result[:endpoint_url] = ($SL_API_ENDPOINT_URL == "API_PUBLIC_ENDPOINT" ? API_PUBLIC_ENDPOINT : API_PRIVATE_ENDPOINT)
161
+ elsif $SL_API_BASE_URL && ENDPOINT_URL_ALIAS.include?($SL_API_BASE_URL)
162
+ result[:endpoint_url] = ($SL_API_BASE_URL == "API_PUBLIC_ENDPOINT" ? API_PUBLIC_ENDPOINT : API_PRIVATE_ENDPOINT)
163
+ elsif ($SL_API_BASE_URL && ! ENDPOINT_URL_ALIAS.include?($SL_API_BASE_URL)) ||
164
+ ($SL_API_ENDPOINT_URL && ! ENDPOINT_URL_ALIAS.include?($SL_API_ENDPOINT_URL))
165
+ result[:endpoint_url] = $SL_API_ENDPOINT_URL || $SL_API_BASE_URL
166
+ end
167
+
168
+ begin
169
+ result[:timeout] = Integer($SL_API_TIMEOUT) if $SL_API_TIMEOUT
170
+ rescue => integer_parse_exception
171
+ raise "Expected the value of the timeout configuration property, '#{$SL_API_TIMEOUT}', to be parseable as an integer"
172
+ end
173
+
174
+ result
175
+ end
176
+ end
121
177
  end
@@ -17,7 +17,15 @@ module SoftLayer
17
17
  # represent.
18
18
 
19
19
  class Datacenter < SoftLayer::ModelBase
20
+
21
+ ##
22
+ # :attr_reader:
23
+ # A short location description
20
24
  sl_attr :name
25
+
26
+ ##
27
+ # :attr_reader: long_name
28
+ # A longer location description
21
29
  sl_attr :long_name, "longName"
22
30
 
23
31
  ##
@@ -30,7 +38,7 @@ module SoftLayer
30
38
  # Return a list of all the datacenters
31
39
  #
32
40
  # If the client parameter is not provided, the routine
33
- # will try to use Client::defult_client. If no client
41
+ # will try to use Client::default_client. If no client
34
42
  # can be found, the routine will raise an exception
35
43
  #
36
44
  # This routine will only retrieve the list of datacenters from
@@ -50,4 +58,4 @@ module SoftLayer
50
58
  @@data_centers
51
59
  end
52
60
  end
53
- end
61
+ end
@@ -7,7 +7,7 @@
7
7
  module SoftLayer
8
8
 
9
9
  ##
10
- # This module is inteneded to be used by classes in the SoftLayer
10
+ # This module is intended to be used by classes in the SoftLayer
11
11
  # object model. It creates a small DSL for creating attributes
12
12
  # that update themselves dynamically (usually by making requests
13
13
  # to the SoftLayer API)
@@ -9,7 +9,7 @@ module SoftLayer
9
9
  ##
10
10
  # A Virtual Server Image Template.
11
11
  #
12
- # This class rougly corresponds to the unwieldily named
12
+ # This class roughly corresponds to the unwieldily named
13
13
  # +SoftLayer_Virtual_Guest_Block_Device_Template_Group+
14
14
  # service:
15
15
  #
@@ -23,12 +23,12 @@ module SoftLayer
23
23
  sl_attr :name
24
24
 
25
25
  ##
26
- # :attr_reader:
26
+ # :attr_reader: notes
27
27
  # The notes, if any, that are attached to the template. Can be nil.
28
28
  sl_attr :notes, "note"
29
29
 
30
30
  ##
31
- # :attr_reader:
31
+ # :attr_reader: global_id
32
32
  # The universally unique identifier (if any) for the template. Can be nil.
33
33
  sl_attr :global_id, 'globalIdentifier'
34
34
 
@@ -91,7 +91,7 @@ module SoftLayer
91
91
  # appear in this array! The list given must be comprehensive.
92
92
  #
93
93
  # The available_datacenters call returns a list of the values that are valid
94
- # whithin this array.
94
+ # within this array.
95
95
  def datacenters=(datacenters_array)
96
96
  datacenter_data = datacenters_array.collect do |datacenter|
97
97
  { "id" => datacenter.id }
@@ -160,7 +160,7 @@ module SoftLayer
160
160
  end
161
161
 
162
162
  ##
163
- # Repeatedly poll the netwokr API until transactions related to this image
163
+ # Repeatedly poll the network API until transactions related to this image
164
164
  # template are finished
165
165
  #
166
166
  # A template is not 'ready' until all the transactions on the template
@@ -209,8 +209,17 @@ module SoftLayer
209
209
  # If no client can be found the routine will raise an error.
210
210
  #
211
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
212
+ # * <b>+:name+</b> (string/array) - Return templates with the given name
213
+ # * <b>+:global_id+</b> (string/array) - Return templates with the given global identifier
214
+ # * <b>+:tags+</b> (string/array) - Return templates with the tags
215
+ #
216
+ # Additionally you may provide options related to the request itself:
217
+ #
218
+ # * <b>*:object_filter*</b> (ObjectFilter) - Include private image templates for templates that matche the
219
+ # criteria of this object filter
220
+ # * <b>+:object_mask+</b> (string, hash, or array) - The object mask of properties you wish to receive for the items returned.
221
+ # If not provided, the result will use the default object mask
222
+ # * <b>+:result_limit+</b> (hash with :limit, and :offset keys) - Limit the scope of results returned.
214
223
  def self.find_private_templates(options_hash = {})
215
224
  softlayer_client = options_hash[:client] || Client.default_client
216
225
  raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !softlayer_client
@@ -223,8 +232,9 @@ module SoftLayer
223
232
  end
224
233
 
225
234
  option_to_filter_path = {
226
- :name => "privateBlockDeviceTemplateGroups.name",
235
+ :name => "privateBlockDeviceTemplateGroups.name",
227
236
  :global_id => "privateBlockDeviceTemplateGroups.globalIdentifier",
237
+ :tags => "privateBlockDeviceTemplateGroups.tagReferences.tag.name"
228
238
  }
229
239
 
230
240
  # For each of the options in the option_to_filter_path map, if the options hash includes
@@ -234,34 +244,17 @@ module SoftLayer
234
244
  object_filter.modify { |filter| filter.accept(filter_path).when_it is(options_hash[option])} if options_hash[option]
235
245
  end
236
246
 
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
247
  account_service = softlayer_client[:Account]
249
248
  account_service = account_service.object_filter(object_filter) unless object_filter.empty?
250
249
  account_service = account_service.object_mask(default_object_mask)
250
+ account_service = account_service.object_mask(options_hash[:object_mask]) if options_hash[:object_mask]
251
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)
252
+ if options_hash[:result_limit] && options_hash[:result_limit][:offset] && options_hash[:result_limit][:limit]
253
+ account_service = account_service.result_limit(options_hash[:result_limit][:offset], options_hash[:result_limit][:limit])
261
254
  end
262
255
 
263
256
  templates_data = account_service.getPrivateBlockDeviceTemplateGroups
264
- templates_data.collect { |template_data| new(softlayer_client, template_data) }
257
+ templates_data.collect { |template_data| ImageTemplate.new(softlayer_client, template_data) }
265
258
  end
266
259
 
267
260
  ##
@@ -275,8 +268,17 @@ module SoftLayer
275
268
  # If no client can be found the routine will raise an error.
276
269
  #
277
270
  # 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
271
+ # * <b>+:name+</b> (string/array) - Return templates with the given name
272
+ # * <b>+:global_id+</b> (string/array) - Return templates with the given global identifier
273
+ # * <b>+:tags+</b> (string/array) - Return templates with the tags
274
+ #
275
+ # Additionally you may provide options related to the request itself:
276
+ #
277
+ # * <b>*:object_filter*</b> (ObjectFilter) - Include public image templates for templates that matche the
278
+ # criteria of this object filter
279
+ # * <b>+:object_mask+</b> (string, hash, or array) - The object mask of properties you wish to receive for the items returned.
280
+ # If not provided, the result will use the default object mask
281
+ # * <b>+:result_limit+</b> (hash with :limit, and :offset keys) - Limit the scope of results returned.
280
282
  def self.find_public_templates(options_hash = {})
281
283
  softlayer_client = options_hash[:client] || Client.default_client
282
284
  raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !softlayer_client
@@ -289,8 +291,9 @@ module SoftLayer
289
291
  end
290
292
 
291
293
  option_to_filter_path = {
292
- :name => "name",
294
+ :name => "name",
293
295
  :global_id => "globalIdentifier",
296
+ :tags => "tagReferences.tag.name"
294
297
  }
295
298
 
296
299
  # For each of the options in the option_to_filter_path map, if the options hash includes
@@ -299,39 +302,22 @@ module SoftLayer
299
302
  option_to_filter_path.each do |option, filter_path|
300
303
  object_filter.modify { |filter| filter.accept(filter_path).when_it is(options_hash[option])} if options_hash[option]
301
304
  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("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
305
 
314
306
  template_service = softlayer_client[:Virtual_Guest_Block_Device_Template_Group]
315
307
  template_service = template_service.object_filter(object_filter) unless object_filter.empty?
316
308
  template_service = template_service.object_mask(default_object_mask)
309
+ template_service = template_service.object_mask(options_hash[:object_mask]) if options_hash[:object_mask]
317
310
 
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)
311
+ if options_hash[:result_limit] && options_hash[:result_limit][:offset] && options_hash[:result_limit][:limit]
312
+ template_service = template_service.result_limit(options_hash[:result_limit][:offset], options_hash[:result_limit][:limit])
327
313
  end
328
314
 
329
315
  templates_data = template_service.getPublicImages
330
- templates_data.collect { |template_data| new(softlayer_client, template_data) }
316
+ templates_data.collect { |template_data| ImageTemplate.new(softlayer_client, template_data) }
331
317
  end
332
318
 
333
319
  ##
334
- # Retrive the Image Template with the given ID
320
+ # Retrieve the Image Template with the given ID
335
321
  # (Note! This is the service ID, not the globalIdentifier!)
336
322
  #
337
323
  # The options parameter should contain:
@@ -348,14 +334,11 @@ module SoftLayer
348
334
  raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !softlayer_client
349
335
 
350
336
  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
337
+ service = service.object_mask(default_object_mask)
338
+ service = service.object_mask(options_hash[:object_mask]) if options_hash[:object_mask]
356
339
 
357
340
  template_data = service.getObject
358
- new(softlayer_client, template_data)
341
+ ImageTemplate.new(softlayer_client, template_data)
359
342
  end
360
343
 
361
344
  ##
@@ -391,4 +374,4 @@ module SoftLayer
391
374
  return "mask[id,accountId,name,note,globalIdentifier,datacenters,blockDevices,tagReferences,publicFlag,flexImageFlag,transactionId,children.transactionId]"
392
375
  end
393
376
  end
394
- end
377
+ end