2011-02-17 13:44:46 -05:00
|
|
|
module Fog
|
2011-06-16 19:28:54 -04:00
|
|
|
module Compute
|
|
|
|
class Ecloud
|
2011-02-17 13:44:46 -05:00
|
|
|
class Server < Fog::Ecloud::Model
|
2012-11-27 19:57:16 -05:00
|
|
|
extend Forwardable
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
identity :href
|
2011-02-17 13:44:46 -05:00
|
|
|
|
2012-11-27 19:57:16 -05:00
|
|
|
attribute :description, :aliases => :Description
|
|
|
|
attribute :hardware_configuration, :aliases => :HardwareConfiguration
|
|
|
|
attribute :ip_addresses, :aliases => :IpAddresses, :squash => :AssignedIpAddresses
|
|
|
|
attribute :layout, :aliases => :Layout
|
|
|
|
attribute :name, :aliases => :Name
|
|
|
|
attribute :operating_system, :aliases => :OperatingSystem
|
|
|
|
attribute :other_links, :aliases => :Links, :squash => :Link
|
|
|
|
attribute :powered_on, :aliases => :PoweredOn, :type => :boolean
|
|
|
|
attribute :status, :aliases => :Status
|
|
|
|
attribute :tags, :aliases => :Tags
|
|
|
|
attribute :tools_status, :aliases => :ToolsStatus
|
|
|
|
attribute :type, :aliases => :Type
|
|
|
|
|
|
|
|
def cpus
|
|
|
|
hardware_configuration.processor_count
|
|
|
|
end
|
|
|
|
|
|
|
|
def memory # always in MB
|
|
|
|
hardware_configuration.memory.to_i
|
|
|
|
end
|
|
|
|
|
|
|
|
def location
|
|
|
|
end
|
|
|
|
|
|
|
|
def flavor_id
|
|
|
|
{:ram => hardware_configuration.memory.to_i, :cpus => hardware_configuration.processor_count}
|
|
|
|
end
|
|
|
|
|
|
|
|
def storage
|
|
|
|
hardware_configuration.storage[:Disk]
|
|
|
|
end
|
2011-02-17 13:44:46 -05:00
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def tasks
|
2012-12-22 18:27:38 -05:00
|
|
|
@tasks ||= self.service.tasks(:href => "/cloudapi/ecloud/tasks/virtualMachines/#{id}")
|
2012-06-07 12:50:11 -04:00
|
|
|
end
|
2011-02-17 13:44:46 -05:00
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def processes
|
2012-12-22 18:27:38 -05:00
|
|
|
@processes ||= Fog::Compute::Ecloud::GuestProcesses.new(:service, service, :href => "/cloudapi/ecloud/virtualMachines/#{id}/guest/processes")
|
2012-06-07 12:50:11 -04:00
|
|
|
end
|
2011-02-17 13:44:46 -05:00
|
|
|
|
2012-11-27 19:57:16 -05:00
|
|
|
def hardware_configuration=(hardware_configuration)
|
2012-12-22 18:27:38 -05:00
|
|
|
@hardware_configuration = self.service.hardware_configurations.new(hardware_configuration)
|
2012-11-27 19:57:16 -05:00
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def hardware_configuration
|
2012-12-22 18:27:38 -05:00
|
|
|
@hardware_configuration ||= self.service.hardware_configurations.new(:href => "/cloudapi/ecloud/virtualMachines/#{id}/hardwareConfiguration")
|
2012-11-27 19:57:16 -05:00
|
|
|
@hardware_configuration.reload
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def configuration
|
2012-12-22 18:27:38 -05:00
|
|
|
@configuration ||= Fog::Compute::Ecloud::ServerConfigurationOptions.new(:service => service, :href => "/cloudapi/ecloud/virtualMachines/#{id}/configurationOptions")[0]
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def ips
|
2012-12-22 18:27:38 -05:00
|
|
|
@ips = self.service.virtual_machine_assigned_ips(:virtual_machine_id => self.id)
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def networks
|
2012-12-22 18:27:38 -05:00
|
|
|
@networks ||= self.service.networks(:href => "/cloudapi/ecloud/virtualMachines/#{id}/assignedIps")
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def power_on
|
|
|
|
power_operation( :power_on => :powerOn )
|
|
|
|
end
|
|
|
|
|
|
|
|
def power_off
|
|
|
|
power_operation( :power_off => :powerOff )
|
|
|
|
end
|
|
|
|
|
|
|
|
def shutdown
|
|
|
|
power_operation( :power_shutdown => :shutdown )
|
|
|
|
end
|
|
|
|
|
|
|
|
def power_reset
|
2012-06-07 12:50:11 -04:00
|
|
|
power_operation( :power_reset => :reboot )
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def delete
|
2012-12-22 18:27:38 -05:00
|
|
|
data = service.virtual_machine_delete(href).body
|
|
|
|
self.service.tasks.new(data)
|
2012-06-07 12:50:11 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def copy(options = {})
|
|
|
|
options = {:type => :copy}.merge(options)
|
|
|
|
options[:source] ||= href
|
|
|
|
if options[:type] == :copy
|
|
|
|
options[:cpus] ||= 1
|
|
|
|
options[:memory] ||= 512
|
|
|
|
options[:customization] ||= :linux
|
|
|
|
options[:tags] ||= []
|
|
|
|
options[:powered_on] ||= false
|
|
|
|
if options[:ips]
|
|
|
|
options[:ips] = options[:ips].is_a?(String) ? [options[:ips]] : options[:ips]
|
|
|
|
else
|
|
|
|
options[:network_uri] = options[:network_uri].is_a?(String) ? [options[:network_uri]] : options[:network_uri]
|
|
|
|
options[:network_uri].each do |uri|
|
|
|
|
index = options[:network_uri].index(uri)
|
2012-12-22 18:27:38 -05:00
|
|
|
ip = Fog::Compute::Ecloud::IpAddresses.new(:service => service, :href => uri).detect { |i| i.host == nil }.name
|
2012-06-07 12:50:11 -04:00
|
|
|
options[:ips] ||= []
|
|
|
|
options[:ips][index] = ip
|
|
|
|
end
|
|
|
|
end
|
2012-12-22 18:27:38 -05:00
|
|
|
data = service.virtual_machine_copy("/cloudapi/ecloud/virtualMachines/computePools/#{compute_pool_id}/action/copyVirtualMachine", options).body
|
2012-06-07 12:50:11 -04:00
|
|
|
elsif options[:type] == :identical
|
2012-12-22 18:27:38 -05:00
|
|
|
data = service.virtual_machine_copy_identical("/cloudapi/ecloud/virtualMachines/computePools/#{compute_pool_id}/action/copyIdenticalVirtualMachine", options).body
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
2012-06-07 12:50:11 -04:00
|
|
|
vm = collection.from_data(data)
|
|
|
|
vm
|
|
|
|
end
|
|
|
|
|
|
|
|
def rnats
|
2012-12-22 18:27:38 -05:00
|
|
|
rnats = Fog::Compute::Ecloud::Rnats.new(:service => service, :href => "/cloudapi/ecloud/rnats/environments/#{environment_id}")
|
2012-06-07 12:50:11 -04:00
|
|
|
associations = nil
|
|
|
|
rnats.each do |rnat|
|
|
|
|
if rnats.index(rnat) == 0
|
|
|
|
associations = rnat.associations.select do |association|
|
|
|
|
ips.any? do |ip|
|
|
|
|
association.name == ip.name
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
rnat.associations.select do |association|
|
|
|
|
ips.each do |ip|
|
|
|
|
if ip.name == association.name
|
|
|
|
associations << association
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
associations
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def edit(options = {})
|
2012-12-22 18:27:38 -05:00
|
|
|
data = service.virtual_machine_edit(href, options).body
|
2012-06-07 12:50:11 -04:00
|
|
|
if data[:type] == "application/vnd.tmrk.cloud.task"
|
2012-12-22 18:27:38 -05:00
|
|
|
task = Fog::Compute::Ecloud::Tasks.new(:service => service, :href => data[:href])[0]
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def create_rnat(options)
|
|
|
|
options[:host_ip_href] ||= ips.first.href
|
|
|
|
options[:uri] = "/cloudapi/ecloud/rnats/environments/#{environment_id}/action/createAssociation"
|
2012-12-22 18:27:38 -05:00
|
|
|
data = service.rnat_associations_create_device(options).body
|
|
|
|
rnat = Fog::Compute::Ecloud::Associations.new(:service => service, :href => data[:href])[0]
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
2012-12-22 18:27:38 -05:00
|
|
|
|
2011-02-17 13:44:46 -05:00
|
|
|
def disks
|
2012-11-27 19:57:16 -05:00
|
|
|
c = hardware_configuration.reload.storage
|
2012-06-07 12:50:11 -04:00
|
|
|
c = c.is_a?(Hash) ? [c] : c
|
|
|
|
@disks = c
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def add_disk(size)
|
2012-06-07 12:50:11 -04:00
|
|
|
index = disks.map { |d| d[:Index].to_i }.sort[-1] + 1
|
2012-11-27 19:57:16 -05:00
|
|
|
vm_disks = disks << {:Index => index.to_s, :Size=>{:Unit => "GB", :Value => size.to_s}, :Name => "Hard Disk #{index + 1}"}
|
2012-12-22 18:27:38 -05:00
|
|
|
data = service.virtual_machine_edit_hardware_configuration(href + "/hardwareConfiguration", _configuration_data(:disks => vm_disks)).body
|
|
|
|
task = self.service.tasks.new(data)
|
2012-11-27 19:57:16 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def detach_disk(index)
|
|
|
|
options = {}
|
|
|
|
options[:disk] = disks.detect { |disk_hash| disk_hash[:Index] == index.to_s }
|
|
|
|
options[:name] = self.name
|
|
|
|
options[:description] = self.description
|
2012-12-22 18:27:38 -05:00
|
|
|
data = service.virtual_machine_detach_disk(href + "/hardwareconfiguration/disks/actions/detach", options).body
|
|
|
|
detached_disk = self.service.detached_disks.new(data)
|
2012-11-27 19:57:16 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def attach_disk(detached_disk)
|
|
|
|
options = {}
|
|
|
|
options[:name] = detached_disk.name
|
|
|
|
options[:href] = detached_disk.href
|
2012-12-22 18:27:38 -05:00
|
|
|
data = service.virtual_machine_attach_disk(href + "/hardwareconfiguration/disks/actions/attach", options).body
|
|
|
|
task = self.service.tasks.new(data)
|
2012-11-27 19:57:16 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def delete_disk(index)
|
|
|
|
vm_disks = disks.delete_if { |h| h[:Index] == index.to_s }
|
2012-12-22 18:27:38 -05:00
|
|
|
data = service.virtual_machine_edit_hardware_configuration(href + "/hardwareconfiguration", _configuration_data(:disks => vm_disks)).body
|
|
|
|
task = self.service.tasks.new(data)
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def nics
|
2012-11-27 19:57:16 -05:00
|
|
|
c = hardware_configuration.network_cards
|
2012-06-07 12:50:11 -04:00
|
|
|
c = c.is_a?(Hash) ? [c] : c
|
|
|
|
@nics = c
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def add_nic(network)
|
|
|
|
unit_number = nics.map { |n| n[:UnitNumber].to_i }.sort[-1] + 1
|
|
|
|
vm_nics = nics << {:UnitNumber => unit_number, :Network => {:href => network.href, :name => network.name, :type => "application/vnd.tmrk.cloud.network"}}
|
2012-12-22 18:27:38 -05:00
|
|
|
data = service.virtual_machine_edit_hardware_configuration(href + "/hardwareConfiguration", _configuration_data(:nics => vm_nics)).body
|
|
|
|
task = self.service.tasks.new(:href => data[:href])[0]
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
2012-08-09 13:23:42 -04:00
|
|
|
def add_ip(options)
|
2012-11-27 19:57:16 -05:00
|
|
|
slice_ips = begin
|
|
|
|
ips
|
|
|
|
rescue
|
|
|
|
[]
|
|
|
|
end
|
|
|
|
slice_networks = if slice_ips.empty?
|
|
|
|
[]
|
|
|
|
else
|
|
|
|
ips.map { |ip| {:href => ip.network.href, :name => ip.network.name.split(' ')[0], :type => ip.network.type} }.push({:href => options[:href], :name => options[:network_name], :type => "application/vnd.tmrk.cloud.network"}).uniq
|
|
|
|
end
|
|
|
|
slice_ips = slice_ips.map { |i| {:name => i.address.name, :network_name => i.network.name} }.push({:name => options[:ip], :network_name => options[:network_name]}).uniq
|
2012-08-09 13:23:42 -04:00
|
|
|
slice_ips.each do |ip|
|
|
|
|
slice_networks.each do |network|
|
|
|
|
if network[:name] == ip[:network_name]
|
|
|
|
network[:ips] ||= []
|
|
|
|
network[:ips].push(ip[:name])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2012-12-22 18:27:38 -05:00
|
|
|
data = service.virtual_machine_edit_assigned_ips(href + "/assignedIps", slice_networks).body
|
|
|
|
task = self.service.tasks.new(data)
|
2012-11-27 19:57:16 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def delete_ip(options)
|
|
|
|
slice_ips = begin
|
|
|
|
ips
|
|
|
|
rescue
|
|
|
|
[]
|
|
|
|
end
|
|
|
|
slice_networks = if slice_ips.empty?
|
|
|
|
[]
|
|
|
|
else
|
|
|
|
ips.map do |ip|
|
|
|
|
{
|
|
|
|
:href => ip.network.href,
|
|
|
|
:name => ip.network.name.split(' ')[0],
|
|
|
|
:type => ip.network.type,
|
|
|
|
}
|
|
|
|
end#.delete_if { |ip| ip[:href] == options[:href] && ip[:name] == options[:network_name] }
|
|
|
|
end
|
|
|
|
slice_ips.map! { |i| {:name => i.address.name, :network_name => i.network.name, :network_name => i.network.name } }.delete_if { |ip| ip[:name] == options[:ip] }
|
|
|
|
slice_ips.each do |ip|
|
|
|
|
slice_networks.each do |network|
|
|
|
|
if network[:name] == ip[:network_name]
|
|
|
|
network[:ips].delete(ip[:name])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2012-12-22 18:27:38 -05:00
|
|
|
data = service.virtual_machine_edit_assigned_ips(href + "/assignedips", slice_networks).body
|
|
|
|
task = self.service.tasks.new(data)
|
2012-08-09 13:23:42 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def upload_file(options)
|
2012-12-22 18:27:38 -05:00
|
|
|
service.virtual_machine_upload_file(href + "/guest/action/files", options)
|
2012-08-09 13:23:42 -04:00
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def storage_size
|
|
|
|
vm_disks = disks
|
2012-11-27 19:57:16 -05:00
|
|
|
disks.map! { |d| d[:Size][:Value].to_i }.inject(0){|sum,item| sum + item} * 1024 * 1024
|
2012-06-07 12:50:11 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def ready?
|
|
|
|
load_unless_loaded!
|
|
|
|
unless status =~ /NotDeployed|Orphaned|TaskInProgress|CopyInProgress/
|
|
|
|
true
|
2011-02-17 13:44:46 -05:00
|
|
|
else
|
2012-06-07 12:50:11 -04:00
|
|
|
false
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def on?
|
|
|
|
powered_on == true
|
|
|
|
end
|
2011-02-17 13:44:46 -05:00
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def off?
|
|
|
|
powered_on == false
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def compute_pool_id
|
2012-11-27 19:57:16 -05:00
|
|
|
other_links.detect { |l| l[:type] == "application/vnd.tmrk.cloud.computePool" }[:href].scan(/\d+/)[0]
|
|
|
|
end
|
|
|
|
|
|
|
|
def compute_pool
|
|
|
|
reload if other_links.nil?
|
2012-12-22 18:27:38 -05:00
|
|
|
@compute_pool = self.service.compute_pools.new(:href => other_links.detect { |l| l[:type] == "application/vnd.tmrk.cloud.computePool" }[:href])
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def environment_id
|
2012-11-27 19:57:16 -05:00
|
|
|
other_links.detect { |l| l[:type] == "application/vnd.tmrk.cloud.environment" }[:href].scan(/\d+/)[0]
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
def id
|
|
|
|
href.scan(/\d+/)[0]
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
2012-06-07 12:50:11 -04:00
|
|
|
private
|
|
|
|
|
|
|
|
def _configuration_data(options = {})
|
2012-11-27 19:57:16 -05:00
|
|
|
{:cpus => (options[:cpus] || hardware_configuration.processor_count), :memory => (options[:memory] || hardware_configuration.memory), :disks => (options[:disks] || disks), :nics => (options[:nics] || nics)}
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def power_operation(op)
|
|
|
|
requires :href
|
|
|
|
begin
|
2012-12-22 18:27:38 -05:00
|
|
|
service.send(op.keys.first, href + "/action/#{op.values.first}" )
|
2012-06-07 12:50:11 -04:00
|
|
|
rescue Excon::Errors::Conflict => e
|
2011-02-17 13:44:46 -05:00
|
|
|
#Frankly we shouldn't get here ...
|
|
|
|
raise e unless e.to_s =~ /because it is already powered o(n|ff)/
|
|
|
|
end
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2012-11-27 19:57:16 -05:00
|
|
|
alias destroy delete
|
2011-02-17 13:44:46 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|