Class: SoftLayer::VirtualServer

Inherits:
Server show all
Includes:
DynamicAttribute
Defined in:
lib/softlayer/VirtualServer.rb

Overview

Instance of this class represent servers that are virtual machines in the SoftLayer environment.

This class roughly corresponds to the entity SoftLayer_Virtual_Guest in the API.

Instance Attribute Summary

Attributes inherited from ModelBase

#softlayer_client

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DynamicAttribute

included

Methods inherited from Server

#change_port_speed, #datacenter, #domain, #fullyQualifiedDomainName, #hostname, #initialize, #notes, #notes=, #primary_private_ip, #primary_public_ip, #reload_os!, #set_domain!, #set_hostname!, #softlayer_properties, #to_s, #user_metadata=

Methods inherited from ModelBase

#[], #has_sl_property?, #initialize, #refresh_details, sl_attr, #to_ary

Constructor Details

This class inherits a constructor from SoftLayer::Server

Class Method Details

.default_object_maskObject

Returns the default object mask used when fetching servers from the API



330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'lib/softlayer/VirtualServer.rb', line 330

def self.default_object_mask
  sub_mask = {
    "mask(SoftLayer_Virtual_Guest)" => [
      'createDate',
      'modifyDate',
      'provisionDate',
      'dedicatedAccountHostOnlyFlag',
      'lastKnownPowerState.name',
      'powerState',
      'status',
      'maxCpu',
      'maxMemory',
      'activeTransaction[id, transactionStatus[friendlyName,name]]',
      'networkComponents[id, status, speed, maxSpeed, name, macAddress, primaryIpAddress, port, primarySubnet]',
      'lastOperatingSystemReload.id',
      'blockDevices',
      'blockDeviceTemplateGroup[id, name, globalIdentifier]'
    ]
  }

  super.merge(sub_mask)
end

.find_servers(options_hash = {}) ⇒ Object

Retrieve a list of virtual servers from the account.

The options parameter should contain:

:client - The client used to connect to the API

If no client is given, then the routine will try to use Client.default_client If no client can be found the routine will raise an error.

You may filter the list returned by adding options:

  • :hourly (boolean) - Include servers billed hourly in the list

  • :monthly (boolean) - Include servers billed monthly in the list

  • :tags (array) - an array of strings representing tags to search for on the instances

  • :cpus (int) - return virtual servers with the given number of (virtual) CPUs

  • :memory (int) - return servers with at least the given amount of memory (in MB. e.g. 4096 = 4GB)

  • :hostname (string) - return servers whose hostnames match the query string given (see ObjectFilter::query_to_filter_operation)

  • :domain (string) - filter servers to those whose domain matches the query string given (see ObjectFilter::query_to_filter_operation)

  • :local_disk (boolean) - include servers that do, or do not, have local disk storage

  • :datacenter (string) - find servers whose short data center name (e.g. dal05, sjc01) matches the query string given (see ObjectFilter::query_to_filter_operation)

  • :nic_speed (int) - include servers with the given nic speed (in Mbps, usually 10, 100, or 1000)

  • :public_ip (string) - return servers whose public IP address matches the query string given (see ObjectFilter::query_to_filter_operation)

  • :private_ip (string) - same as :public_ip, but for private IP addresses

Additionally you may provide options related to the request itself:

  • :object_mask (string) - A object mask of properties, in addition to the default properties, that you wish to retrieve for the servers

  • :result_limit (hash with :limit, and :offset keys) - Limit the scope of results returned.



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/softlayer/VirtualServer.rb', line 257

def self.find_servers(options_hash = {})
  softlayer_client = options_hash[:client] || Client.default_client
  raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !softlayer_client

  object_filter = {}

  option_to_filter_path = {
    :cpus => "virtualGuests.maxCpu",
    :memory => "virtualGuests.maxMemory",
    :hostname => "virtualGuests.hostname",
    :domain => "virtualGuests.domain",
    :local_disk => "virtualGuests.localDiskFlag",
    :datacenter => "virtualGuests.datacenter.name",
    :nic_speed => "virtualGuests.networkComponents.maxSpeed",
    :public_ip => "virtualGuests.primaryIpAddress",
    :private_ip => "virtualGuests.primaryBackendIpAddress"
  }

  if options_hash.has_key?(:local_disk) then
    options_hash[:local_disk] = options_hash[:local_disk] ? 1 : 0
  end

  # For each of the options in the option_to_filter_path map, if the options hash includes
  # that particular option, add a clause to the object filter that filters for the matching
  # value
  option_to_filter_path.each do |option, filter_path|
    object_filter.merge!(SoftLayer::ObjectFilter.build(filter_path, options_hash[option])) if options_hash.has_key?(option)
  end

  # Tags get a much more complex object filter operation so we handle them separately
  if options_hash.has_key?(:tags)
    object_filter.merge!(SoftLayer::ObjectFilter.build("virtualGuests.tagReferences.tag.name", {
      'operation' => 'in',
      'options' => [{
        'name' => 'data',
        'value' => options_hash[:tags]
        }]
      } ));
  end

  required_properties_mask = 'mask.id'

   = softlayer_client['Account']
   = .object_filter(object_filter) unless object_filter.empty?
   = .object_mask(default_object_mask.to_sl_object_mask)

  if options_hash.has_key? :object_mask
     = .object_mask(options_hash[:object_mask])
  end

  if options_hash.has_key?(:result_limit)
    offset = options[:result_limit][:offset]
    limit = options[:result_limit][:limit]

     = .result_limit(offset, limit)
  end

  case
  when options_hash[:hourly] && options_hash[:monthly]
    virtual_server_data = .getVirtualGuests()
  when options_hash[:hourly]
    virtual_server_data = .getHourlyVirtualGuests()
  when options_hash[:monthly]
    virtual_server_data = .getMonthlyVirtualGuests()
  else
    virtual_server_data = .getVirtualGuests()
  end

  virtual_server_data.collect { |server_data| VirtualServer.new(softlayer_client, server_data) }
end

.server_with_id(server_id, options = {}) ⇒ Object

Retrive the virtual server with the given server ID from the API

The options parameter should contain:

:client - The client used to connect to the API

If no client is given, then the routine will try to use Client.default_client If no client can be found the routine will raise an error.

The options may include the following keys

  • :object_mask (string) - A object mask of properties, in addition to the default properties, that you wish to retrieve for the server



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/softlayer/VirtualServer.rb', line 213

def self.server_with_id(server_id, options = {})
  softlayer_client = options[:client] || Client.default_client
  raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !softlayer_client

  vg_service = softlayer_client["Virtual_Guest"]
  vg_service = vg_service.object_mask(default_object_mask.to_sl_object_mask)

  if options.has_key?(:object_mask)
    vg_service = vg_service.object_mask(options[:object_mask])
  end

  server_data = vg_service.object_with_id(server_id).getObject()

  return VirtualServer.new(softlayer_client, server_data)
end

Instance Method Details

#activeTransactionObject

:attr_reader: The active transaction (if any) for this virtual server. Transactions are used to make configuration changes to the server and only one transaction can be active at a time.



55
# File 'lib/softlayer/VirtualServer.rb', line 55

sl_attr :activeTransaction

#blockDevicesObject

:attr_reader: Storage devices attached to the server. Storage may be local to the host running the Virtual Server, or it may be located on the SAN



62
# File 'lib/softlayer/VirtualServer.rb', line 62

sl_attr :blockDevices

#cancel!Object

IMMEDIATELY cancel this virtual server



89
90
91
# File 'lib/softlayer/VirtualServer.rb', line 89

def cancel!
  self.service.deleteObject()
end

#capture_image(image_name, include_attached_storage = false, image_notes = nil) ⇒ Object

Capture a disk image of this virtual server for use with other servers.

image_name will become the name of the image in the portal.

If include_attached_storage is true, the images of attached storage will be included as well.

The image_notes should be a string and will be added to the image as notes.



146
147
148
149
150
151
152
153
# File 'lib/softlayer/VirtualServer.rb', line 146

def capture_image(image_name, include_attached_storage = false, image_notes = nil)
  disk_filter = lambda { |disk| disk['device'] == '0' }
  disk_filter = lambda { |disk| disk['device'] == '1' } if include_attached_storage

  disks = self.blockDevices.select(&disk_filter)

  self.service.createArchiveTransaction(image_name, disks, notes) if disks && !disks.empty?
end

#coresObject

:attr_reader: A count of the nubmer of virtual processing cores allocated to the server.



40
# File 'lib/softlayer/VirtualServer.rb', line 40

sl_attr :cores, 'maxCpu'

#lastOperatingSystemReloadObject

:attr_reader: The last operating system reload transaction that was run for this server. #wait_until_ready compares the ID of this transaction to the ID of the active transaction to determine if an OS reload is in progress.



70
# File 'lib/softlayer/VirtualServer.rb', line 70

sl_attr :lastOperatingSystemReload

#provisionDateObject

:attr_reader: The date the Virtual Server was provisioned. This attribute can be nil if the SoftLayer system has not yet finished provisioning the server (consequently this attribute is used by the #wait_until_ready method to determine when a server has been provisioned)



48
# File 'lib/softlayer/VirtualServer.rb', line 48

sl_attr :provisionDate

#serviceObject

Returns the SoftLayer Service that represents calls to this object For VirtualServers the service is SoftLayer_Virtual_Guest and addressing this object is done by id.



357
358
359
# File 'lib/softlayer/VirtualServer.rb', line 357

def service
  return softlayer_client["Virtual_Guest"].object_with_id(self.id)
end

#upgrade_cores!(num_cores) ⇒ Object

This routine submits an order to upgrade the cpu count of the virtual server. The order may result in additional charges being applied to SoftLayer account

This routine can also “downgrade” servers (set their cpu count lower)

The routine returns true if the order is placed and false if it is not



101
102
103
104
105
# File 'lib/softlayer/VirtualServer.rb', line 101

def upgrade_cores!(num_cores)
  upgrade_item_price = _item_price_in_category("guest_core", num_cores)
  _order_upgrade_item!(upgrade_item_price) if upgrade_item_price
  nil != upgrade_item_price
end

#upgrade_max_port_speed!(network_speed_in_Mbps) ⇒ Object

This routine submits an order to change the maximum nic speed of the server Pass in the desired speed in Megabits per second (typically 10, 100, or 1000) (since you may choose a slower speed this routine can also be used for “downgrades”)

The order may result in additional charges being applied to SoftLayer account

The routine returns true if the order is placed and false if it is not



130
131
132
133
134
# File 'lib/softlayer/VirtualServer.rb', line 130

def upgrade_max_port_speed!(network_speed_in_Mbps)
  upgrade_item_price = _item_price_in_category("port_speed", network_speed_in_Mbps)
  _order_upgrade_item!(upgrade_item_price) if upgrade_item_price
  nil != upgrade_item_price
end

#upgrade_optionsObject

A virtual server can find out about items that are available for upgrades.



76
77
78
79
80
81
82
83
84
# File 'lib/softlayer/VirtualServer.rb', line 76

sl_dynamic_attr :upgrade_options do |resource|
  resource.should_update? do
    @upgrade_options == nil
  end

  resource.to_update do
    self.service.object_mask("mask[id,categories.categoryCode,item[id,capacity,units,attributes,prices]]").getUpgradeItemPrices(true)
  end
end

#upgrade_RAM!(ram_in_GB) ⇒ Object

This routine submits an order to change the RAM available to the virtual server. Pass in the desired amount of RAM for the server in Gigabytes

The order may result in additional charges being applied to SoftLayer account

The routine returns true if the order is placed and false if it is not



115
116
117
118
119
# File 'lib/softlayer/VirtualServer.rb', line 115

def upgrade_RAM!(ram_in_GB)
  upgrade_item_price = _item_price_in_category("ram", ram_in_GB)
  _order_upgrade_item!(upgrade_item_price) if upgrade_item_price
  nil != upgrade_item_price
end

#wait_until_ready(max_trials, wait_for_transactions = false, seconds_between_tries = 2) ⇒ Object

Repeatedly polls the API to find out if this server is ‘ready’.

The server is ready when it is provisioned and any operating system reloads have completed.

If wait_for_transactions is true, then the routine will poll until all transactions (not just an OS Reload) have completed on the server.

max_trials is the maximum number of times the routine will poll the API seconds_between_tries is the polling interval (in seconds)

The routine returns true if the server was found to be ready. If max_trials is exceeded and the server is still not ready, the routine returns false

If a block is passed to this routine it will be called on each trial with a boolean argument representing whether or not the server is ready

Calling this routine will (in essence) block the thread on which the request is made.



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/softlayer/VirtualServer.rb', line 174

def wait_until_ready(max_trials, wait_for_transactions = false, seconds_between_tries = 2)
  # pessimistically assume the server is not ready
  num_trials = 0
  begin
    self.refresh_details()

    has_os_reload = has_sl_property? :lastOperatingSystemReload
    has_active_transaction = has_sl_property? :activeTransaction

    reloading_os = has_active_transaction && has_os_reload && (self.lastOperatingSystemReload['id'] == self.activeTransaction['id'])
    provisioned = has_sl_property? :provisionDate

    # a server is ready when it is provisioned, not reloading the OS
    # (and if wait_for_transactions is true, when there are no active transactions).
    ready = provisioned && !reloading_os && (!wait_for_transactions || !has_active_transaction)

    num_trials = num_trials + 1

    yield ready if block_given?

    sleep(seconds_between_tries) if !ready && (num_trials <= max_trials)
  end until ready || (num_trials >= max_trials)

  ready
end