Class: Fog::Compute::Softlayer::Server

Inherits:
Fog::Compute::Server
  • Object
show all
Defined in:
lib/fog/softlayer/models/compute/server.rb

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}) ⇒ Server

Returns a new instance of Server.

Raises:

  • (Exception)


52
53
54
55
56
57
# File 'lib/fog/softlayer/models/compute/server.rb', line 52

def initialize(attributes = {})
  # Forces every request inject bare_metal parameter
  raise Exception if attributes[:collection].nil? and attributes['bare_metal'].nil?
  super(attributes)
  set_defaults
end

Instance Method Details

#active_transactionObject



266
267
268
269
270
271
272
# File 'lib/fog/softlayer/models/compute/server.rb', line 266

def active_transaction
  if bare_metal?
    service.request(:hardware_server, "#{id}/getActiveTransaction").body
  else
    service.request(:virtual_guest, "#{id}/getActiveTransaction").body
  end
end

#add_tags(tags) ⇒ Object

Raises:

  • (ArgumentError)


59
60
61
62
63
64
65
66
67
# File 'lib/fog/softlayer/models/compute/server.rb', line 59

def add_tags(tags)
  requires :id
  raise ArgumentError, "Tags argument for #{self.class.name}##{__method__} must be Array." unless tags.is_a?(Array)
  tags.each do |tag|
    service.tags.new(:resource_id => self.id, :name => tag).save
  end
  self.reload
  true
end

#bare_metalObject



73
74
75
# File 'lib/fog/softlayer/models/compute/server.rb', line 73

def bare_metal
  @bare_metal
end

#bare_metal?Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/fog/softlayer/models/compute/server.rb', line 69

def bare_metal?
  bare_metal
end

#datacenterObject



82
83
84
# File 'lib/fog/softlayer/models/compute/server.rb', line 82

def datacenter
  attributes[:datacenter][:name] unless attributes[:datacenter].nil?
end

#datacenter=(name) ⇒ Object



77
78
79
80
# File 'lib/fog/softlayer/models/compute/server.rb', line 77

def datacenter=(name)
  name = name['name'] if name.is_a?(Hash)
  attributes[:datacenter] = { :name => name }
end

#delete_tags(tags) ⇒ Object

Raises:

  • (ArgumentError)


86
87
88
89
90
91
92
93
94
# File 'lib/fog/softlayer/models/compute/server.rb', line 86

def delete_tags(tags)
  requires :id
  raise ArgumentError, "Tags argument for #{self.class.name}##{__method__} must be Array." unless tags.is_a?(Array)
  tags.each do |tag|
    service.tags.new(:resource_id => self.id, :name => tag).destroy
  end
  self.reload
  true
end

#destroyObject



96
97
98
99
100
101
# File 'lib/fog/softlayer/models/compute/server.rb', line 96

def destroy
  requires :id
  request = bare_metal? ? :delete_bare_metal_server : :delete_vm
  response = service.send(request, self.id)
  response.body
end

#dns_nameObject



103
104
105
# File 'lib/fog/softlayer/models/compute/server.rb', line 103

def dns_name
  fqdn
end

#generate_order_templateObject



400
401
402
403
404
405
# File 'lib/fog/softlayer/models/compute/server.rb', line 400

def generate_order_template
  copy = self.dup
  copy.pre_save
  return service.generate_bare_metal_order_template(copy.attributes).body if copy.bare_metal?
  service.generate_virtual_guest_order_template(copy.attributes).body
end

#get_active_ticketsObject



377
378
379
380
# File 'lib/fog/softlayer/models/compute/server.rb', line 377

def get_active_tickets
  return service.get_bare_metal_active_tickets(id).body if bare_metal?
  service.get_virtual_guest_active_tickets(id).body
end

#get_upgrade_optionsObject



387
388
389
390
# File 'lib/fog/softlayer/models/compute/server.rb', line 387

def get_upgrade_options
  return service.get_bare_metal_upgrade_item_prices(id).body if bare_metal?
  service.get_virtual_guest_upgrade_item_prices(id).body
end

#get_usersObject



382
383
384
385
# File 'lib/fog/softlayer/models/compute/server.rb', line 382

def get_users
  return service.get_bare_metal_users(id).body if bare_metal?
  service.get_virtual_guest_users(id).body
end

#image_idObject



111
112
113
# File 'lib/fog/softlayer/models/compute/server.rb', line 111

def image_id
  attributes[:image_id][:globalIdentifier] unless attributes[:image_id].nil?
end

#image_id=(uuid) ⇒ Object



107
108
109
# File 'lib/fog/softlayer/models/compute/server.rb', line 107

def image_id=(uuid)
  attributes[:image_id] = {:globalIdentifier => uuid}
end

#key_pairsObject



187
188
189
# File 'lib/fog/softlayer/models/compute/server.rb', line 187

def key_pairs
  attributes[:key_pairs]
end

#key_pairs=(keys) ⇒ Object

Raises:

  • (ArgumentError)


191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/fog/softlayer/models/compute/server.rb', line 191

def key_pairs=(keys)
  raise ArgumentError, "Argument #{local_variables.first.to_s} for #{self.class.name}##{__method__} must be Array." unless keys.is_a?(Array)
  attributes[:key_pairs] = []
  keys.map do |key|
    ## This was nice but causing an intolerable number of requests on an account with lots of keys.
    ## ToDo: something better...
    #key = self.symbolize_keys(key) if key.is_a?(Hash)
    #unless key.is_a?(Fog::Compute::Softlayer::KeyPair) or (key.is_a?(Hash) and key[:id])
    #  raise ArgumentError, "Elements of keys array for #{self.class.name}##{__method__} must be a Hash with key 'id', or Fog::Compute::Softlayer::KeyPair"
    #end
    #key = service.key_pairs.get(key[:id]) unless key.is_a?(Fog::Compute::Softlayer::KeyPair)
    attributes[:key_pairs] << key
  end
end

#nameObject



119
120
121
# File 'lib/fog/softlayer/models/compute/server.rb', line 119

def name
  attributes[:hostname]
end

#name=(set) ⇒ Object



115
116
117
# File 'lib/fog/softlayer/models/compute/server.rb', line 115

def name=(set)
  attributes[:hostname] = set
end

#network_componentsObject



242
243
244
245
246
247
248
# File 'lib/fog/softlayer/models/compute/server.rb', line 242

def network_components
  if id
    (public_network_components << private_network_components).flatten
  else
    attributes[:network_components]
  end
end

#os_codeObject



160
161
162
# File 'lib/fog/softlayer/models/compute/server.rb', line 160

def os_code
  attributes['operatingSystem']['softwareLicense']['softwareDescription']['referenceCode'] if attributes['operatingSystem']
end

#pre_saveObject



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/fog/softlayer/models/compute/server.rb', line 123

def pre_save
  extract_flavor
  self.bare_metal = true if attributes[:fixed_configuration_preset] and not bare_metal?
  validate_attributes
  if self.vlan
    attributes[:vlan] = { :networkVlan => { :id => self.vlan.id } }
  end
  if self.private_vlan
    attributes[:private_vlan] = { :networkVlan => { :id => self.private_vlan.id } }
  end
  if self.key_pairs
    attributes[:key_pairs].map! { |key| { :id => key.respond_to?(:id) ? key.id : key } }
  end
  if self.network_components
    self.network_components = self.network_components.map do |component|
      component['maxSpeed'] = component.delete('speed') if component['speed']
      component['maxSpeed'] = component.delete('max_speed') if component['max_speed']
      component
    end
  end

  if attributes[:fixed_configuration_preset].is_a? String
      attributes[:fixedConfigurationPreset] = {:keyName => attributes.delete(:fixed_configuration_preset)}
  end

  remap_attributes(attributes, attributes_mapping)
  clean_attributes
end

#private_ipObject

maintain backward compatibility with <0.3.13



152
153
154
# File 'lib/fog/softlayer/models/compute/server.rb', line 152

def private_ip # maintain backward compatibility with <0.3.13
  private_ip_address
end

#private_network_componentsObject



258
259
260
261
262
263
264
# File 'lib/fog/softlayer/models/compute/server.rb', line 258

def private_network_components
  if attributes['backendNetworkComponents']
    attributes['backendNetworkComponents'].map { |n| Fog::Compute::Softlayer::NetworkComponent.new(n) }
  else
    []
  end
end

#private_vlanObject



164
165
166
# File 'lib/fog/softlayer/models/compute/server.rb', line 164

def private_vlan
  attributes[:private_vlan] ||= _get_private_vlan
end

#private_vlan=(value) ⇒ Object



168
169
170
171
172
173
174
# File 'lib/fog/softlayer/models/compute/server.rb', line 168

def private_vlan=(value)
  unless value.is_a?(Integer) or value.is_a?(Fog::Network::Softlayer::Network)
    raise ArgumentError, "vlan argument for #{self.class.name}##{__method__} must be Integer or Fog::Network::Softlayer::Network."
  end
  value = network_connection.networks.get(value) if value.is_a?(Integer)
  attributes[:private_vlan] = value
end

#provision_scriptObject



238
239
240
# File 'lib/fog/softlayer/models/compute/server.rb', line 238

def provision_script
  attributes[:provision_script]
end

#provision_script=(value) ⇒ Object



234
235
236
# File 'lib/fog/softlayer/models/compute/server.rb', line 234

def provision_script=(value)
  attributes[:provision_script] = value
end

#public_ipObject

maintain backward compatibility with <0.3.13



156
157
158
# File 'lib/fog/softlayer/models/compute/server.rb', line 156

def public_ip # maintain backward compatibility with <0.3.13
  public_ip_address
end

#public_network_componentsObject



250
251
252
253
254
255
256
# File 'lib/fog/softlayer/models/compute/server.rb', line 250

def public_network_components
  if attributes['frontendNetworkComponents']
    attributes['frontendNetworkComponents'].map { |n| Fog::Compute::Softlayer::NetworkComponent.new(n) }
  else
    []
  end
end

#ram=(set) ⇒ Object



218
219
220
221
222
223
# File 'lib/fog/softlayer/models/compute/server.rb', line 218

def ram=(set)
  if set.is_a?(Array) and set.first['hardwareComponentModel']
    set = 1024 * set.first['hardwareComponentModel']['capacity'].to_i
  end
  attributes[:ram] = set
end

#ready?Boolean

Returns:

  • (Boolean)


274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/fog/softlayer/models/compute/server.rb', line 274

def ready?
  begin
    if active_transaction
      false
    elsif bare_metal?
      state == "on"
    else
      state == "Running"
    end
  rescue Excon::Errors::InternalServerError => e
    false
  end
end

#reboot(use_hard_reboot = true) ⇒ Object



288
289
290
291
292
293
294
295
296
# File 'lib/fog/softlayer/models/compute/server.rb', line 288

def reboot(use_hard_reboot = true)
  # requires :id # TODO: debug why this breaks the tests on bare metal and uncomment this
  if bare_metal?
    service.reboot_bare_metal_server(id, use_hard_reboot)
  else
    service.reboot_vm(id, use_hard_reboot)
  end
  true
end

#relaunch!Object

reload the OS on a server (method name reload was already taken)



177
178
179
180
181
182
183
184
185
# File 'lib/fog/softlayer/models/compute/server.rb', line 177

def relaunch!
  requires :id
  body = [ "FORCE", {}]
  body[1][:sshKeyIds] = key_pairs.map {|kp| kp.id} unless key_pairs.empty?
  type = bare_metal? ? :hardware_server : :virtual_guest
  status = service.request(type, "#{id}/reloadOperatingSystem", :body => body, :http_method => :post).status
  wait_for { not ready? } # block until the relaunch has begun
  [200, 201].include?(status)
end

#saveObject

Note:

You should use servers.create to create servers instead calling this method directly

Creates server

  • requires attributes: :name, :domain, and :flavor_id OR (:cpu_count && :ram && :disks)

  • State Transitions

    • BUILD -> ACTIVE

    • BUILD -> ERROR (on error)

Raises:

  • (Fog::Errors::Error)


357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/fog/softlayer/models/compute/server.rb', line 357

def save
  raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
  copy = self.dup
  copy.pre_save

  data = if copy.bare_metal?
    service.create_bare_metal_server(copy.attributes).body
  else
    service.create_vm(copy.attributes).body.first
  end

  data.delete("bare_metal")
  merge_attributes(data)
  true
end

#shutdownObject

Soft power off



331
332
333
334
335
336
337
338
339
# File 'lib/fog/softlayer/models/compute/server.rb', line 331

def shutdown
  # requires :id # TODO: debug why this breaks the tests on bare metal and uncomment this
  if bare_metal?
    raise Fog::Errors::Error.new('Shutdown not supported on baremetal servers. Use #stop.')
  else
    service.power_off_vm(id, false)
  end
  true
end

#snapshotObject



305
306
307
# File 'lib/fog/softlayer/models/compute/server.rb', line 305

def snapshot
  # TODO: implement
end

#ssh_passwordObject



298
299
300
301
302
303
# File 'lib/fog/softlayer/models/compute/server.rb', line 298

def ssh_password
  requires :id
  service_path = bare_metal? ? :hardware_server : :virtual_guest
  @sshpass ||= service.request(service_path, id, :query => 'objectMask=mask[id,operatingSystem.passwords[password]]').body
  @sshpass['operatingSystem']['passwords'][0]['password'] unless @sshpass['operatingSystem'].nil? or @sshpass['operatingSystem']['passwords'].empty?
end

#startObject



309
310
311
312
313
314
315
316
317
# File 'lib/fog/softlayer/models/compute/server.rb', line 309

def start
  # requires :id # TODO: debug why this breaks the tests on bare metal and uncomment this
  if bare_metal?
    service.power_on_bare_metal_server(id)
  else
    service.power_on_vm(id)
  end
  true
end

#stateObject



341
342
343
344
345
346
347
# File 'lib/fog/softlayer/models/compute/server.rb', line 341

def state
  if bare_metal?
    service.request(:hardware_server, "#{id}/getServerPowerState").body
  else
    service.request(:virtual_guest, "#{id}/getPowerState").body['name']
  end
end

#stopObject

Hard power off



320
321
322
323
324
325
326
327
328
# File 'lib/fog/softlayer/models/compute/server.rb', line 320

def stop
  # requires :id # TODO: debug why this breaks the tests on bare metal and uncomment this
  if bare_metal?
    service.power_off_bare_metal_server(id)
  else
    service.power_off_vm(id, true)
  end
  true
end

#tagsObject



373
374
375
# File 'lib/fog/softlayer/models/compute/server.rb', line 373

def tags
  attributes[:tags].map { |i| i['tag']['name'] if i['tag'] }.compact if attributes[:tags]
end

#update(update_attributes) ⇒ Object

Raises:

  • (ArgumentError)


392
393
394
395
396
397
398
# File 'lib/fog/softlayer/models/compute/server.rb', line 392

def update(update_attributes)
  raise ArgumentError if update_attributes.nil?
  product_connection
  prices = get_item_prices_id(update_attributes)
  order = generate_upgrade_order(prices, update_attributes[:time] || update_attributes[:maintenance_window])
  @product_conn.place_order(order).body
end

#user_dataObject



230
231
232
# File 'lib/fog/softlayer/models/compute/server.rb', line 230

def user_data
  attributes[:user_data]
end

#user_data=(value) ⇒ Object



226
227
228
# File 'lib/fog/softlayer/models/compute/server.rb', line 226

def user_data=(value)
  attributes[:user_data] = [{'value' => value}]
end

#vlanObject



206
207
208
# File 'lib/fog/softlayer/models/compute/server.rb', line 206

def vlan
  attributes[:vlan] ||= _get_vlan
end

#vlan=(value) ⇒ Object



210
211
212
213
214
215
216
# File 'lib/fog/softlayer/models/compute/server.rb', line 210

def vlan=(value)
  unless value.is_a?(Integer) or value.is_a?(Fog::Network::Softlayer::Network)
    raise ArgumentError, "vlan argument for #{self.class.name}##{__method__} must be Integer or Fog::Network::Softlayer::Network."
  end
  value = network_connection.networks.get(value) if value.is_a?(Integer)
  attributes[:vlan] = value
end

#wait_for_id(timeout = 14400, delay = 30) ⇒ Object



407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
# File 'lib/fog/softlayer/models/compute/server.rb', line 407

def wait_for_id(timeout=14400, delay=30)
  # Cannot use self.wait_for because it calls reload which requires
  # self.id which is not initially available for bare metal.
  filterStr = Fog::JSON.encode({
    "hardware" => {
      "hostname" => {
        "operation" => self.name,
      },
      "domain" => {
        "operation" => self.domain,
      },
      "globalIdentifier" => {
        "operation" => self.uid,
      },
    }
  })

  Fog.wait_for(timeout, delay) do
    res = service.request(:account, 'getHardware', :query => {
      :objectMask => 'mask[id,fullyQualifiedDomainName,provisionDate,hardwareStatus,lastTransaction[elapsedSeconds,transactionStatus[friendlyName]],operatingSystem[id,passwords[password,username]]]',
      :objectFilter => filterStr,
    })

    server = res.body.first

    yield server if block_given?

    if server and server["provisionDate"]
        attributes[:id] = server['id']
        true
    else
        false
    end
  end

  self.reload
  true
end