class Fog::Compute::Vsphere::Real
Public Class Methods
# File lib/fog/vsphere/compute.rb, line 547 def initialize(options={}) require 'rbvmomi' @vsphere_username = options[:vsphere_username] @vsphere_password = options[:vsphere_password] @vsphere_server = options[:vsphere_server] @vsphere_port = options[:vsphere_port] || 443 @vsphere_path = options[:vsphere_path] || '/sdk' @vsphere_ns = options[:vsphere_ns] || 'urn:vim25' @vsphere_rev = options[:vsphere_rev] || '4.0' @vsphere_ssl = options[:vsphere_ssl] || true @vsphere_debug = options[:vsphere_debug] || false @vsphere_expected_pubkey_hash = options[:vsphere_expected_pubkey_hash] @vsphere_must_reauthenticate = false @vsphere_is_vcenter = nil @connection = nil connect negotiate_revision(options[:vsphere_rev]) authenticate end
Public Instance Methods
# File lib/fog/vsphere/requests/compute/modify_vm_cdrom.rb, line 5 def add_vm_cdrom(cdrom) vm_reconfig_hardware('instance_uuid' => cdrom.server.instance_uuid, 'hardware_spec' => {'deviceChange'=>[create_cdrom(cdrom, cdrom.unit_number, :add)]}) end
# File lib/fog/vsphere/requests/compute/modify_vm_controller.rb, line 5 def add_vm_controller(controller) vm_reconfig_hardware('instance_uuid' => controller.server_id, 'hardware_spec' => {'deviceChange'=>[create_controller(controller)]}) end
# File lib/fog/vsphere/requests/compute/modify_vm_interface.rb, line 5 def add_vm_interface(vmid, options = {}) raise ArgumentError, "instance id is a required parameter" unless vmid interface = get_interface_from_options(vmid, options.merge(:server_id => vmid)) vm_reconfig_hardware('instance_uuid' => vmid, 'hardware_spec' => {'deviceChange'=>[create_interface(interface, 0, :add, options)]}) end
# File lib/fog/vsphere/requests/compute/modify_vm_volume.rb, line 5 def add_vm_volume(volume) vm_reconfig_hardware('instance_uuid' => volume.server_id, 'hardware_spec' => {'deviceChange'=>[create_disk(volume, :add)]}) end
# File lib/fog/vsphere/requests/compute/cloudinit_to_customspec.rb, line 5 def cloudinit_to_customspec(user_data) raise ArgumentError, "user_data can't be nil" if user_data.nil? custom_spec = { 'customization_spec' => Hash.new } user_data = YAML.load(user_data) # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.Specification.html # encryptionKey expects an array # globalIPSettings expects a hash, REQUIRED # identity expects an hash, REQUIRED # nicSettingMap expects an array # options expects an hash custom_spec['encryptionKey'] = user_data['encryptionKey'] if user_data.key?('encryptionKey') custom_spec['globalIPSettings'] = user_data['globalIPSettings'] if user_data.key?('globalIPSettings') custom_spec['identity'] = user_data['identity'] if user_data.key?('identity') custom_spec['identity'] = {"Sysprep"=>{"guiRunOnce"=>{"commandList"=>user_data['runcmd']}}} if user_data.key?('runcmd') and not user_data.key?('identity') custom_spec['nicSettingMap'] = user_data['nicSettingMap'] if user_data.key?('nicSettingMap') custom_spec['options'] = user_data['options'] if user_data.key?('options') # for backwards compatability # hostname expects a string, REQUIRED # netmask expects a string # dns expects an array # gateway expects an array # domain expects a string, REQUIRED # domainsuffixlist expects an array, REQUIRED # timezone expects a string, for example Europe/Copenhagen, REQUIRED custom_spec['hostname'] = user_data['hostname'] if user_data.key?('hostname') custom_spec['ipsettings'] = { 'ip' => user_data['ip'] } if user_data.key?('ip') custom_spec['ipsettings']['subnetMask'] = user_data['netmask'] if user_data.key?('netmask') custom_spec['ipsettings']['dnsServerList'] = user_data['dns'] if user_data.key?('dns') custom_spec['ipsettings']['gateway'] = user_data['gateway'] if user_data.key?('gateway') custom_spec['domain'] = user_data['domain'] if user_data.key?('domain') custom_spec['dnsSuffixList'] = user_data['domainsuffixlist'] if user_data.key?('domainsuffixlist') custom_spec['time_zone'] = user_data['timezone'] if user_data.key?('timezone') custom_spec end
# File lib/fog/vsphere/compute.rb, line 567 def connection if @connection.nil? || @connection.serviceContent.sessionManager.currentSession.nil? Fog::Logger.debug('Reconnecting to vSphere.') @connection = nil reload end @connection end
# File lib/fog/vsphere/requests/compute/create_folder.rb, line 5 def create_folder(datacenter, path, name) #Path cannot be nil but it can be an empty string raise ArgumentError, "Path cannot be nil" if path.nil? parent_folder = get_raw_vmfolder(path, datacenter) begin new_folder = parent_folder.CreateFolder(:name => name) # output is cleaned up to return the new path # new path will be path/name, example: "Production/Pool1" new_folder.path.reject { |a| a.first.class == "Folder" }.map { |a| a.first.name }.join("/").sub(/^\/?Datacenters\/#{datacenter}\/vm\/?/, '') end end
# File lib/fog/vsphere/requests/compute/create_group.rb, line 5 def create_group(attributes={}) cluster = get_raw_cluster(attributes[:cluster], attributes[:datacenter]) group = cluster.configurationEx.group.find {|n| n[:name] == attributes[:name]} if group raise ArgumentError, "Group #{attributes[:name]} already exists!" end spec = get_group_spec attributes cluster_spec = RbVmomi::VIM.ClusterConfigSpecEx(groupSpec: [ RbVmomi::VIM.ClusterGroupSpec( operation: RbVmomi::VIM.ArrayUpdateOperation('add'), info: spec ) ]) cluster.ReconfigureComputeResource_Task(spec: cluster_spec, modify: true).wait_for_completion group = cluster.configurationEx.group.find {|n| n[:name] == attributes[:name]} if group return group[:name] else raise Fog::Vsphere::Errors::ServiceError, "Unknown error creating group #{attributes[:name]}" end end
# File lib/fog/vsphere/requests/compute/create_rule.rb, line 5 def create_rule(attributes={}) cluster = get_raw_cluster(attributes[:cluster], attributes[:datacenter]) rule = cluster.configurationEx.rule.find {|n| n[:name] == attributes[:name]} if rule raise ArgumentError, "Rule #{attributes[:name]} already exists!" end spec = get_rule_spec attributes # Now, attach it to the cluster cluster_spec = RbVmomi::VIM.ClusterConfigSpecEx(rulesSpec: [ RbVmomi::VIM.ClusterRuleSpec( operation: RbVmomi::VIM.ArrayUpdateOperation('add'), info: spec ) ]) ret = cluster.ReconfigureComputeResource_Task(spec: cluster_spec, modify: true).wait_for_completion rule = cluster.configurationEx.rule.find {|n| n[:name] == attributes[:name]} if rule return rule[:key] else raise Fog::Vsphere::Errors::ServiceError, "Unknown error creating rule #{attributes[:name]}" end end
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 5 def create_vm attributes = { } # build up vm configuration vm_cfg = { :name => attributes[:name], :annotation => attributes[:annotation], :guestId => attributes[:guest_id], :version => attributes[:hardware_version], :files => { :vmPathName => vm_path_name(attributes) }, :numCPUs => attributes[:cpus], :numCoresPerSocket => attributes[:corespersocket], :memoryMB => attributes[:memory_mb], :deviceChange => device_change(attributes), :extraConfig => extra_config(attributes), } vm_cfg[:cpuHotAddEnabled] = attributes[:cpuHotAddEnabled] if attributes.key?(:cpuHotAddEnabled) vm_cfg[:memoryHotAddEnabled] = attributes[:memoryHotAddEnabled] if attributes.key?(:memoryHotAddEnabled) vm_cfg[:firmware] = attributes[:firmware] if attributes.key?(:firmware) vm_cfg[:bootOptions] = boot_options(attributes, vm_cfg) if attributes.key?(:boot_order) || attributes.key?(:boot_retry) resource_pool = if attributes[:resource_pool] && attributes[:resource_pool] != 'Resources' get_raw_resource_pool(attributes[:resource_pool], attributes[:cluster], attributes[:datacenter]) else get_raw_cluster(attributes[:cluster], attributes[:datacenter]).resourcePool end vmFolder = get_raw_vmfolder(attributes[:path], attributes[:datacenter]) if attributes.key?(:host) host = get_raw_host(attributes[:host], attributes[:cluster], attributes[:datacenter]) else host = nil end # if any volume has a storage_pod set, we deploy the vm on a storage pod instead of the defined datastores pod = get_storage_pod(attributes) if pod vm = create_vm_on_storage_pod(pod, vm_cfg, vmFolder, resource_pool, attributes[:datacenter], host) else vm = create_vm_on_datastore(vm_cfg, vmFolder, resource_pool, host) end vm.config.instanceUuid end
# File lib/fog/vsphere/requests/compute/current_time.rb, line 5 def current_time current_time = connection.serviceInstance.CurrentTime { 'current_time' => current_time } end
# File lib/fog/vsphere/requests/compute/destroy_group.rb, line 5 def destroy_group(attributes = {}) cluster = get_raw_cluster(attributes[:cluster], attributes[:datacenter]) group = cluster.configurationEx.group.find {|g| g.name == attributes[:name]} raise Fog::Vsphere::Error::NotFound, "group #{attributes[:name]} not found" unless group delete_spec = RbVmomi::VIM.ClusterConfigSpecEx(groupSpec: [ RbVmomi::VIM.ClusterGroupSpec( operation: RbVmomi::VIM.ArrayUpdateOperation('remove'), removeKey: group.name ) ]) cluster.ReconfigureComputeResource_Task(spec: delete_spec, modify: true).wait_for_completion end
# File lib/fog/vsphere/requests/compute/destroy_rule.rb, line 5 def destroy_rule(attributes = {}) cluster = get_raw_cluster(attributes[:cluster], attributes[:datacenter]) rule = cluster.configurationEx.rule.find {|rule| rule.key == attributes[:key]} raise Fog::Vsphere::Error::NotFound, "rule #{attributes[:key]} not found" unless rule delete_spec = RbVmomi::VIM.ClusterConfigSpecEx(rulesSpec: [ RbVmomi::VIM.ClusterRuleSpec( operation: RbVmomi::VIM.ArrayUpdateOperation('remove'), removeKey: rule.key ) ]) cluster.ReconfigureComputeResource_Task(spec: delete_spec, modify: true).wait_for_completion end
# File lib/fog/vsphere/requests/compute/modify_vm_cdrom.rb, line 9 def destroy_vm_cdrom(cdrom) vm_reconfig_hardware('instance_uuid' => cdrom.server.instance_uuid, 'hardware_spec' => {'deviceChange'=>[create_cdrom(cdrom, cdrom.unit_number, :remove)]}) end
# File lib/fog/vsphere/requests/compute/modify_vm_interface.rb, line 12 def destroy_vm_interface(vmid, options = {}) raise ArgumentError, "instance id is a required parameter" unless vmid interface = get_interface_from_options(vmid, options.merge(:server_id => vmid)) vm_reconfig_hardware('instance_uuid' => vmid, 'hardware_spec' => {'deviceChange'=>[create_interface(interface, interface.key, :remove)]}) end
# File lib/fog/vsphere/requests/compute/modify_vm_volume.rb, line 13 def destroy_vm_volume(volume) vm_reconfig_hardware('instance_uuid' => volume.server_id, 'hardware_spec' => { 'deviceChange'=>[create_disk(volume, :remove, file_operation: :destroy)] }) end
# File lib/fog/vsphere/requests/compute/folder_destroy.rb, line 5 def folder_destroy(path, datacenter_name) folder = get_raw_vmfolder(path, datacenter_name) raise Fog::Vsphere::Errors::NotFound, "No such folder #{path}" unless folder raise Fog::Vsphere::Errors::ServiceError, "Folder #{path} is not empty" if folder.childEntity.size > 0 task = folder.Destroy_Task task.wait_for_completion { 'task_state' => task.info.state } end
# File lib/fog/vsphere/requests/compute/get_cluster.rb, line 5 def get_cluster(name, datacenter_name) cluster = get_raw_cluster(name, datacenter_name) raise(Fog::Compute::Vsphere::NotFound) unless cluster cluster_attributes(cluster, datacenter_name) end
# File lib/fog/vsphere/requests/compute/get_compute_resource.rb, line 5 def get_compute_resource(name, datacenter_name) compute_resource = get_raw_compute_resource(name, datacenter_name) raise(Fog::Compute::Vsphere::NotFound) unless compute_resource compute_resource_attributes(compute_resource, datacenter_name) end
# File lib/fog/vsphere/requests/compute/get_datacenter.rb, line 5 def get_datacenter name dc = find_raw_datacenter(name) raise(Fog::Compute::Vsphere::NotFound) unless dc {:name => dc.name, :status => dc.overallStatus, :path => raw_getpathmo(dc) } end
# File lib/fog/vsphere/requests/compute/get_datastore.rb, line 5 def get_datastore(name, datacenter_name) datastore = get_raw_datastore(name, datacenter_name) raise(Fog::Compute::Vsphere::NotFound) unless datastore datastore_attributes(datastore, datacenter_name) end
# File lib/fog/vsphere/requests/compute/get_folder.rb, line 5 def get_folder(path, datacenter_name, type = nil) type ||= 'vm' # Cycle through all types of folders. case type when 'vm', :vm # if you're a vm then grab the VM. folder = get_raw_vmfolder(path, datacenter_name) raise(Fog::Compute::Vsphere::NotFound) unless folder folder_attributes(folder, datacenter_name) when 'network', :network raise "not implemented" when 'datastore', :datastore raise "not implemented" else raise ArgumentError, "#{type} is unknown" end end
# File lib/fog/vsphere/requests/compute/get_host.rb, line 6 def get_host(name, cluster_name, datacenter_name) get_raw_host(name, cluster_name, datacenter_name) end
# File lib/fog/vsphere/requests/compute/get_interface_type.rb, line 5 def get_interface_type(id, servertype, datacenter, filter={}) interfacetype=list_interface_types(filters={:id => id, :datacenter => datacenter, :servertype => servertype.id }).first raise(Fog::Compute::Vsphere::NotFound) unless interfacetype interfacetype end
# File lib/fog/vsphere/requests/compute/get_network.rb, line 5 def get_network(name, datacenter_name) network = get_raw_network(name, datacenter_name) raise(Fog::Compute::Vsphere::NotFound) unless network network_attributes(network, datacenter_name) end
# File lib/fog/vsphere/requests/compute/list_vm_interfaces.rb, line 48 def get_raw_interface(vm_id, options={}) raise ArgumentError, "instance id is a required parameter" unless vm_id if options.is_a? Fog::Compute::Vsphere::Interface options else raise ArgumentError, "Either key or name is a required parameter. options: #{options}" unless options.key? :key or options.key? :mac or options.key? :name get_raw_interfaces(vm_id).find do |nic| (options.key? :key and nic.key==options[:key].to_i) or (options.key? :mac and nic.macAddress==options[:mac]) or (options.key? :name and nic.deviceInfo.label==options[:name]) end end end
# File lib/fog/vsphere/requests/compute/list_vm_interfaces.rb, line 44 def get_raw_interfaces(vm_id, datacenter = nil) get_vm_ref(vm_id, datacenter).config.hardware.device.grep(RbVmomi::VIM::VirtualEthernetCard) end
# File lib/fog/vsphere/requests/compute/get_resource_pool.rb, line 5 def get_resource_pool(name, cluster_name, datacenter_name) resource_pool = get_raw_resource_pool(name, cluster_name, datacenter_name) raise(Fog::Compute::Vsphere::NotFound) unless resource_pool resource_pool_attributes(resource_pool, cluster_name, datacenter_name) end
# File lib/fog/vsphere/requests/compute/get_server_type.rb, line 5 def get_server_type(id, datacenter, filter={}) server_type=get_raw_server_type(id, datacenter) raise(Fog::Compute::Vsphere::NotFound) unless server_type server_type_attributes(server_type, datacenter) end
# File lib/fog/vsphere/requests/compute/get_template.rb, line 5 def get_template(id, datacenter_name = nil) convert_vm_mob_ref_to_attr_hash(get_vm_ref(id, datacenter_name)) end
# File lib/fog/vsphere/requests/compute/get_virtual_machine.rb, line 5 def get_virtual_machine(id, datacenter_name = nil, folder = nil, recursive = false) # The larger the VM list the longer it will take if not searching based on UUID. convert_vm_mob_ref_to_attr_hash(get_vm_ref(id, datacenter_name, folder, recursive)) end
# File lib/fog/vsphere/requests/compute/get_vm_first_scsi_controller.rb, line 6 def get_vm_first_scsi_controller(vm_id) Fog::Compute::Vsphere::SCSIController.new(get_vm_first_scsi_controller_raw(vm_id)) end
# File lib/fog/vsphere/requests/compute/get_vm_first_scsi_controller.rb, line 10 def get_vm_first_scsi_controller_raw(vm_id) ctrl=get_vm_ref(vm_id).config.hardware.device.grep(RbVmomi::VIM::VirtualSCSIController).select{ | ctrl | ctrl.key == 1000 }.first { :type => ctrl.class.to_s, :shared_bus => ctrl.sharedBus.to_s, :unit_number => ctrl.scsiCtlrUnitNumber, :key => ctrl.key, } end
# File lib/fog/vsphere/requests/compute/list_vm_interfaces.rb, line 35 def get_vm_interface(vm_id, options={}) raw = get_raw_interface(vm_id, options) if raw raw_to_hash(raw) else nil end end
# File lib/fog/vsphere/requests/compute/host_finish_maintenance.rb, line 5 def host_finish_maintenance(name, cluster_name, datacenter_name, timeout = 0) host_ref = get_host(name, cluster_name, datacenter_name) task = host_ref.ExitMaintenanceMode_Task(:timeout => timeout) task.wait_for_completion { 'task_state' => task.info.state } end
# File lib/fog/vsphere/requests/compute/host_shutdown.rb, line 5 def host_shutdown(name, cluster_name, datacenter_name, force = false) host_ref = get_host(name, cluster_name, datacenter_name) task = host_ref.ShutdownHost_Task(:force => force) task.wait_for_completion { 'task_state' => task.info.state } end
# File lib/fog/vsphere/requests/compute/host_start_maintenance.rb, line 5 def host_start_maintenance(name, cluster_name, datacenter_name, timeout = 0, evacuate_powered_off_vms = false) host_ref = get_host(name, cluster_name, datacenter_name) task = host_ref.EnterMaintenanceMode_Task(:timeout => timeout, :evacuatePoweredOffVms => evacuate_powered_off_vms) task.wait_for_completion { 'task_state' => task.info.state } end
# File lib/fog/vsphere/requests/compute/list_interface_types.rb, line 14 def interface_type_attributes(nic, servertype, datacenter) { :id => nic, :name => nic, :datacenter => datacenter, :servertype => servertype } end
# File lib/fog/vsphere/requests/compute/list_child_snapshots.rb, line 5 def list_child_snapshots(snapshot, opts = {}) normalized_snapshot = Hash === snapshot ? Snapshot.new(snapshot.update(:service => self)) : snapshot child_snapshots = normalized_snapshot.tree_node.childSnapshotList.map do |snap| item = child_snapshot_info(snap, normalized_snapshot) [ item, opts[:recursive] ? list_child_snapshots(item, opts) : nil ] end child_snapshots.flatten.compact end
# File lib/fog/vsphere/requests/compute/list_clusters.rb, line 6 def list_clusters(filters = {}) datacenter_name = filters[:datacenter] if filters.key? :datacenter if datacenter_name.nil? list_datacenters.map { |dc| list_clusters(:datacenter => dc[:name]) }.flatten else raw_clusters(datacenter_name).map do |cluster| if cluster.instance_of? RbVmomi::VIM::ClusterComputeResource cluster_attributes(cluster, datacenter_name) end end.compact end end
# File lib/fog/vsphere/requests/compute/list_compute_resources.rb, line 5 def list_compute_resources(filters = { }) datacenter_name = filters[:datacenter] # default to show all compute_resources only_active = filters[:effective] || false compute_resources = raw_compute_resources datacenter_name compute_resources.map do |compute_resource| unless compute_resource.instance_of? RbVmomi::VIM::Folder summary = compute_resource.summary next if only_active and summary.numEffectiveHosts == 0 compute_resource_attributes(compute_resource, datacenter_name) end end.compact end
# File lib/fog/vsphere/requests/compute/list_customfields.rb, line 5 def list_customfields() connection.serviceContent.customFieldsManager.field.map do |customfield| { :key => customfield.key.to_i, :name => customfield.name, :type => customfield.type } end end
# File lib/fog/vsphere/requests/compute/list_datacenters.rb, line 5 def list_datacenters filters = {} raw_datacenters.map do |dc| { :id => managed_obj_id(dc), :name => dc.name, :path => raw_getpathmo(dc), :status => dc.overallStatus } end end
# File lib/fog/vsphere/requests/compute/list_datastores.rb, line 5 def list_datastores(filters = { }) datacenter_name = filters[:datacenter] cluster_name = filters.fetch(:cluster, nil) # default to show all datastores only_active = filters[:accessible] || false raw_datastores(datacenter_name, cluster_name).map do |datastore| next if only_active and !datastore.summary.accessible datastore_attributes(datastore, datacenter_name) end.compact end
Grabs all sub folders within a given path folder.
Parameters¶ ↑
-
filters<~Hash>:
-
:datacenter<~String> - REQUIRED Your datacenter where you're looking for folders. Example: 'my-datacenter-name' (passed if you are using the models/collections)
eg: vspconn.datacenters.first.vm_folders('mypath')
-
:path<~String> - Your path where you're looking for more folders, if return = none you will get an error. If you don't define it will look in the main datacenter folder for any folders in that datacenter.
-
Example Usage Testing Only:
vspconn = Fog::Compute[:vsphere] mydc = vspconn.datacenters.first folders = mydc.vm_folders
# File lib/fog/vsphere/requests/compute/list_folders.rb, line 23 def list_folders(filters = { }) path = filters[:path] || filters['path'] || '' datacenter_name = filters[:datacenter] get_raw_vmfolders(path, datacenter_name).map do |folder| folder_attributes(folder, datacenter_name) end end
# File lib/fog/vsphere/requests/compute/list_groups.rb, line 5 def list_groups(filters = {}) cluster = get_raw_cluster(filters[:cluster], filters[:datacenter]) cluster.configurationEx.group.map {|g| group_attributes g, filters} end
# File lib/fog/vsphere/requests/compute/list_hosts.rb, line 5 def list_hosts(filters = {}) cluster = get_raw_cluster(filters[:cluster], filters[:datacenter]) results = property_collector_results(host_system_filter_spec(cluster)) results.map do |host| hsh = map_attrs_to_hash(host, host_system_attribute_mapping) hsh.merge( datacenter: filters[:datacenter], cluster: filters[:cluster], ipaddress: (host['config.network.vnic'].first.spec.ip.ipAddress rescue nil), ipaddress6: (host['config.network.vnic'].first.spec.ip.ipV6Config.ipV6Address.first.ipAddress rescue nil), vm_ids: Proc.new { host['vm'].map {|vm| vm.config.instanceUuid rescue nil} } ) end end
# File lib/fog/vsphere/requests/compute/list_interface_types.rb, line 5 def list_interface_types(filters={}) datacenter_name = filters[:datacenter] servertype_name = filters[:servertype] get_raw_server_type(servertype_name, datacenter_name)[:supportedEthernetCard].map do | nictype | next if filters.key?(:id) and filters[:id] != nictype interface_type_attributes(nictype, servertype_name, datacenter_name) end.compact end
# File lib/fog/vsphere/requests/compute/list_networks.rb, line 5 def list_networks(filters = { }) datacenter_name = filters[:datacenter] cluster_name = filters.fetch(:cluster, nil) # default to show all networks only_active = filters[:accessible] || false raw_networks(datacenter_name, cluster_name).map do |network| next if only_active && !network.summary.accessible network_attributes(network, datacenter_name) end.compact end
# File lib/fog/vsphere/requests/compute/list_processes.rb, line 5 def list_processes(vm_id, opts) vm = get_vm_ref(vm_id) auth = RbVmomi::VIM::NamePasswordAuthentication( :username => opts[:user], :password => opts[:password], :interactiveSession => false ) p_manager = connection.serviceContent.guestOperationsManager.processManager processes = p_manager.ListProcessesInGuest(:vm => vm, :auth => auth) processes.map do |pi| Process.new( :cmd_line => pi.cmdLine, :end_time => pi.endTime, :exit_code => pi.exitCode, :name => pi.name, :owner => pi.owner, :pid => pi.pid, :start_time => pi.startTime ) end end
# File lib/fog/vsphere/requests/compute/list_resource_pools.rb, line 5 def list_resource_pools(filters = { }) datacenter_name = filters[:datacenter] cluster_name = filters[:cluster] cluster = get_raw_cluster(cluster_name, datacenter_name) list_raw_resource_pools(cluster).map do |resource_pool| resource_pool_attributes(resource_pool, cluster_name, datacenter_name) end end
# File lib/fog/vsphere/requests/compute/list_rules.rb, line 5 def list_rules(filters = {}) cluster = get_raw_cluster(filters[:cluster], filters[:datacenter]) cluster.configurationEx.rule.map {|r| rule_attributes r, filters} end
# File lib/fog/vsphere/requests/compute/list_server_types.rb, line 5 def list_server_types(filters={}) datacenter_name = filters[:datacenter] servertypes=raw_server_types(datacenter_name) if servertypes servertypes.map do | servertype | server_type_attributes(servertype, datacenter_name) end.compact else nil end #select{ | guestdesc | guestdesc.select{ | k, v | filter.has_key?(k) and filter[k] == v }==filter } end
# File lib/fog/vsphere/requests/compute/list_storage_pods.rb, line 5 def list_storage_pods(filters = { }) datacenter_name = filters[:datacenter] raw_storage_pods(datacenter_name).map do |storage_pod| storage_pod_attributes(storage_pod, datacenter_name) end.compact end
# File lib/fog/vsphere/requests/compute/list_templates.rb, line 5 def list_templates(options = { }) options[:folder] ||= options['folder'] if options[:folder] then list_all_templates_in_folder(options[:folder], options[:datacenter]) else list_all_templates(options) end end
# File lib/fog/vsphere/requests/compute/list_virtual_machines.rb, line 5 def list_virtual_machines(options = { }) # Listing all VM's can be quite slow and expensive. Try and optimize # based on the available options we have. These conditions are in # ascending order of time to complete for large deployments. options[:folder] ||= options['folder'] if options['instance_uuid'] then [get_virtual_machine(options['instance_uuid'])] elsif options[:folder] && options[:datacenter] then list_all_virtual_machines_in_folder(options[:folder], options[:datacenter], options[:recursive]) else list_all_virtual_machines(options) end end
# File lib/fog/vsphere/requests/compute/list_vm_cdroms.rb, line 5 def list_vm_cdroms(vm_id) get_vm_ref(vm_id).config.hardware.device.select { |hw| hw.class == RbVmomi::VIM::VirtualCdrom }.map do |cdrom| { :filename => (cdrom.backing.fileName rescue(nil)), :name => cdrom.deviceInfo.label, :key => cdrom.key, :controller_key => cdrom.controllerKey, :unit_number => cdrom.unitNumber, :start_connected => cdrom.connectable.startConnected, :allow_guest_control => cdrom.connectable.allowGuestControl, :connected => cdrom.connectable.connected, :instance_uuid => vm_id, } end end
# File lib/fog/vsphere/requests/compute/list_vm_customvalues.rb, line 5 def list_vm_customvalues(vm_id) get_vm_ref(vm_id).summary.customValue.map do |customvalue| { :key => customvalue.key.to_i, :value => customvalue.value, } end end
=> VirtualE1000(
addressType: “assigned”, backing: VirtualEthernetCardNetworkBackingInfo(
deviceName: "VM Network", dynamicProperty: [], network: Network("network-163"), useAutoDetect: false
), connectable: VirtualDeviceConnectInfo(
allowGuestControl: true, connected: true, dynamicProperty: [], startConnected: true, status: "ok"
), controllerKey: 100, deviceInfo: Description(
dynamicProperty: [], label: "Network adapter 1", summary: "VM Network"
), dynamicProperty: [], key: 4000, macAddress: “00:50:56:a9:00:28”, unitNumber: 7,
# File lib/fog/vsphere/requests/compute/list_vm_interfaces.rb, line 31 def list_vm_interfaces(vm_id, datacenter = nil) get_raw_interfaces(vm_id, datacenter).map {|nic| raw_to_hash nic} end
# File lib/fog/vsphere/requests/compute/list_vm_scsi_controllers.rb, line 5 def list_vm_scsi_controllers(vm_id) list_vm_scsi_controllers_raw(vm_id).map do |raw_controller| Fog::Compute::Vsphere::SCSIController.new(raw_controller) end end
# File lib/fog/vsphere/requests/compute/list_vm_scsi_controllers.rb, line 11 def list_vm_scsi_controllers_raw(vm_id) get_vm_ref(vm_id).config.hardware.device.grep(RbVmomi::VIM::VirtualSCSIController).map do |ctrl| { :type => ctrl.class.to_s, :shared_bus => ctrl.sharedBus.to_s, :unit_number => ctrl.scsiCtlrUnitNumber, :key => ctrl.key, } end end
# File lib/fog/vsphere/requests/compute/list_vm_snapshots.rb, line 5 def list_vm_snapshots(vm_id, opts = {}) vm_snapshot_info = get_vm_ref(vm_id).snapshot return [] unless vm_snapshot_info root_snapshots = vm_snapshot_info.rootSnapshotList.map do |snap| item = snapshot_info(snap, vm_id) [ item, opts[:recursive] ? list_child_snapshots(item, opts) : nil ] end root_snapshots.flatten.compact end
[VirtualDisk( backing: VirtualDiskFlatVer2BackingInfo( contentId: "a172d19487e878e17d6b16ff2505d7eb", datastore: Datastore("datastore-162"), diskMode: "persistent", dynamicProperty: [], fileName: "[Storage1] rhel6-mfojtik/rhel6-mfojtik.vmdk", split: false, thinProvisioned: true, uuid: "6000C29c-a47d-4cd9-5249-c371de775f06", writeThrough: false ), capacityInKB: 8388608, controllerKey: 1000, deviceInfo: Description( dynamicProperty: [], label: "Hard disk 1", summary: "8,388,608 KB" ), dynamicProperty: [], key: 2001, shares: SharesInfo( dynamicProperty: [], level: "normal", shares: 1000 ), unitNumber: 1
)]
# File lib/fog/vsphere/requests/compute/list_vm_volumes.rb, line 30 def list_vm_volumes(vm_id) get_vm_ref(vm_id).disks.map do |vol| { :id => vol.backing.uuid, :thin => (vol.backing.thinProvisioned rescue(nil)), :mode => vol.backing.diskMode, :filename => vol.backing.fileName, :datastore => (vol.backing.datastore.name rescue(nil)), :size => vol.capacityInKB, :name => vol.deviceInfo.label, :key => vol.key, :unit_number => vol.unitNumber, :controller_key => vol.controllerKey } end end
Build up the network config spec for simple case: simple case: apply just the network_label, nic_type and network_adapter_device_key
# File lib/fog/vsphere/requests/compute/vm_clone.rb, line 717 def modify_template_nics_simple_spec(network_label, nic_type, network_adapter_device_key, datacenter) config_spec_operation = RbVmomi::VIM::VirtualDeviceConfigSpecOperation('edit') # Get the portgroup and handle it from there. network = get_raw_network(network_label, datacenter) if ( network.kind_of? RbVmomi::VIM::DistributedVirtualPortgroup) # Create the NIC backing for the distributed virtual portgroup nic_backing_info = RbVmomi::VIM::VirtualEthernetCardDistributedVirtualPortBackingInfo( :port => RbVmomi::VIM::DistributedVirtualSwitchPortConnection( :portgroupKey => network.key, :switchUuid => network.config.distributedVirtualSwitch.uuid ) ) else # Otherwise it's a non distributed port group nic_backing_info = RbVmomi::VIM::VirtualEthernetCardNetworkBackingInfo(:deviceName => network_label) end connectable = RbVmomi::VIM::VirtualDeviceConnectInfo( :allowGuestControl => true, :connected => true, :startConnected => true) device = RbVmomi::VIM.public_send "#{nic_type}", :backing => nic_backing_info, :deviceInfo => RbVmomi::VIM::Description(:label => "Network adapter 1", :summary => network_label), :key => network_adapter_device_key, :connectable => connectable device_spec = RbVmomi::VIM::VirtualDeviceConfigSpec( :operation => config_spec_operation, :device => device) return device_spec end
# File lib/fog/vsphere/requests/compute/vm_clone.rb, line 749 def modify_template_nics_specs(vm_mob_ref, nics, datacenter) specs = [] template_nics = vm_mob_ref.config.hardware.device.grep(RbVmomi::VIM::VirtualEthernetCard) modified_nics = nics.take(template_nics.size) new_nics = nics.drop(template_nics.size) template_nics.zip(modified_nics).each do |template_nic, new_nic| if new_nic backing = create_nic_backing(new_nic, {datacenter: datacenter}) template_nic.backing = backing template_nic.addressType = 'generated' template_nic.macAddress = nil connectable = RbVmomi::VIM::VirtualDeviceConnectInfo( :allowGuestControl => true, :connected => true, :startConnected => true ) template_nic.connectable = connectable specs << { operation: :edit, device: template_nic } else interface = Fog::Compute::Vsphere::Interface.new(raw_to_hash(template_nic)) specs << create_interface(interface, interface.key, :remove, :datacenter => datacenter) end end new_nics.each do |interface| specs << create_interface(interface, 0, :add, :datacenter => datacenter) end specs end
# File lib/fog/vsphere/requests/compute/vm_clone.rb, line 784 def modify_template_volumes_specs(vm_mob_ref, volumes) template_volumes = vm_mob_ref.config.hardware.device.grep(RbVmomi::VIM::VirtualDisk) modified_volumes = volumes.take(template_volumes.size) new_volumes = volumes.drop(template_volumes.size) specs = [] template_volumes.zip(modified_volumes).each do |template_volume, new_volume| if new_volume # updated the attribtues on the existing volume # it's not allowed to reduce the size of the volume when cloning if new_volume.size > template_volume.capacityInKB template_volume.capacityInKB = new_volume.size end template_volume.backing.diskMode = new_volume.mode template_volume.backing.thinProvisioned = new_volume.thin specs << { :operation => :edit, :device => template_volume } else specs << { :operation => :remove, :fileOperation => :destroy, :device => template_volume } end end specs.concat(new_volumes.map { |volume| create_disk(volume) }) specs end
# File lib/fog/vsphere/requests/compute/list_clusters.rb, line 19 def raw_clusters(datacenter) folder ||= find_raw_datacenter(datacenter).hostFolder @raw_clusters = get_raw_clusters_from_folder(folder) end
# File lib/fog/vsphere/requests/compute/list_compute_resources.rb, line 20 def raw_compute_resources(datacenter_name) find_raw_datacenter(datacenter_name).find_compute_resource('').children end
# File lib/fog/vsphere/requests/compute/list_datastores.rb, line 16 def raw_datastores(datacenter_name, cluster = nil) if cluster.nil? find_raw_datacenter(datacenter_name).datastore else get_raw_cluster(cluster, datacenter_name).datastore end end
# File lib/fog/vsphere/requests/compute/list_networks.rb, line 16 def raw_networks(datacenter_name, cluster = nil) if cluster.nil? find_raw_datacenter(datacenter_name).network else get_raw_cluster(cluster, datacenter_name).network end end
# File lib/fog/vsphere/requests/compute/list_server_types.rb, line 18 def raw_server_types(datacenter_name, filter={}) datacenter=find_raw_datacenter(datacenter_name) environmentBrowser=datacenter.hostFolder.childEntity.grep(RbVmomi::VIM::ComputeResource).first.environmentBrowser if environmentBrowser environmentBrowser.QueryConfigOption[:guestOSDescriptor] end end
# File lib/fog/vsphere/compute.rb, line 576 def reload connect # Check if the negotiation was ever run if @vsphere_is_vcenter.nil? negotiate end authenticate end
# File lib/fog/vsphere/requests/compute/vm_clone.rb, line 810 def relocate_template_volumes_specs(vm_mob_ref, volumes, datacenter) template_volumes = vm_mob_ref.config.hardware.device.grep(RbVmomi::VIM::VirtualDisk) modified_volumes = volumes.take(template_volumes.size) specs = [] template_volumes.zip(modified_volumes).each do |template_volume, new_volume| if new_volume && new_volume.datastore && new_volume.datastore != template_volume.backing.datastore.name specs << { :diskId => template_volume.key, :datastore => get_raw_datastore(new_volume.datastore, datacenter) } end end specs end
# File lib/fog/vsphere/requests/compute/modify_vm_volume.rb, line 9 def remove_vm_volume(volume) vm_reconfig_hardware('instance_uuid' => volume.server_id, 'hardware_spec' => {'deviceChange'=>[create_disk(volume, :remove)]}) end
# File lib/fog/vsphere/requests/compute/revert_to_snapshot.rb, line 5 def revert_to_snapshot(snapshot) unless Snapshot === snapshot fail ArgumentError, 'snapshot is a required parameter' end task = snapshot.mo_ref.RevertToSnapshot_Task task.wait_for_completion { 'state' => task.info.state } end
# File lib/fog/vsphere/requests/compute/set_vm_customvalue.rb, line 5 def set_vm_customvalue(vm_id, key, value) vm_ref = get_vm_ref(vm_id) vm_ref.setCustomValue(:key => key, :value => value) end
# File lib/fog/vsphere/requests/compute/modify_vm_interface.rb, line 19 def update_vm_interface(vmid, options = {}) raise ArgumentError, "instance id is a required parameter" unless vmid interface = get_interface_from_options(vmid, options) raw_interface = get_raw_interface(vmid, key: interface.key) if options[:network] interface.network = options[:network] backing = create_nic_backing(interface, {}) raw_interface.backing = backing end apply_options_to_raw_interface(raw_interface, options) spec = { operation: :edit, device: raw_interface } vm_reconfig_hardware('instance_uuid' => vmid, 'hardware_spec' => {'deviceChange'=>[spec]}) end
# File lib/fog/vsphere/requests/compute/upload_iso.rb, line 19 def upload_iso(options = {}) options = upload_iso_check_options(options) datastore = get_raw_datastore(options['datastore'], options['datacenter']) datacenter = get_raw_datacenter(options['datacenter']) filename = options['filename'] || File.basename(options['local_path']) unless datastore.exists? options['upload_directory']+'/' connection.serviceContent.fileManager.MakeDirectory :name => "[#{options['datastore']}] #{options['upload_directory']}", :datacenter => datacenter, :createParentDirectories => false end datastore.upload options['upload_directory']+'/'+filename, options['local_path'] datastore.exists? options['upload_directory']+'/'+filename end
# File lib/fog/vsphere/requests/compute/upload_iso.rb, line 5 def upload_iso_check_options(options) default_options = { 'upload_directory' => 'isos', } options = default_options.merge(options) required_options = %w{ datacenter datastore local_path } required_options.each do |param| raise ArgumentError, "#{required_options.join(', ')} are required" unless options.key? param end raise Fog::Compute::Vsphere::NotFound, "Datacenter #{options["datacenter"]} Doesn't Exist!" unless get_datacenter(options["datacenter"]) raise Fog::Compute::Vsphere::NotFound, "Datastore #{options["datastore"]} Doesn't Exist!" unless get_raw_datastore(options['datastore'], options['datacenter']) options end
# File lib/fog/vsphere/requests/compute/vm_acquire_ticket.rb, line 5 def vm_acquire_ticket(options = {}) raise ArgumentError, "instance_uuid is a required parameter" unless options.key?('instance_uuid') ticket_type = options['ticket_type'] || 'webmks' vm_mob_ref = get_vm_ref(options['instance_uuid']) ticket = vm_mob_ref.AcquireTicket(:ticketType => ticket_type) { 'ticket' => ticket.ticket, 'host' => ticket.host, 'port' => ticket.port, 'ssl_thumbprint' => ticket.sslThumbprint } end
Clones a VM from a template or existing machine on your vSphere Server.
Parameters¶ ↑
-
options<~Hash>:
-
'datacenter'<~String> - REQUIRED Datacenter name your cloning in. Make sure this datacenter exists, should if you're using the clone function in server.rb model.
-
'template_path'<~String> - REQUIRED The path to the machine you want to clone FROM. Relative to Datacenter (Example: “FolderNameHere/VMNameHere”)
-
'name'<~String> - REQUIRED The VMName of the Destination
-
'dest_folder'<~String> - Destination Folder of where 'name' will be placed on your cluster. Relative Path to Datacenter E.G. “FolderPlaceHere/anotherSub Folder/onemore”
-
'power_on'<~Boolean> - Whether to power on machine after clone. Defaults to true.
-
'wait'<~Boolean> - Whether the method should wait for the virtual machine to finish cloning before returning information from vSphere. Broken right now as you cannot return a model of a serer that isn't finished cloning. Defaults to True
-
'resource_pool'<~Array> - The resource pool on your datacenter cluster you want to use. Only works with clusters within same same datacenter as where you're cloning from. Datacenter grabbed from template_path option. Example: ['cluster_name_here','resource_pool_name_here']
-
'datastore'<~String> - The datastore you'd like to use.
(datacenterObj.datastoreFolder.find('name') in API)
-
'storage_pod'<~String> - The storage pod / datastore cluster you'd like to use.
-
'transform'<~String> - Not documented - see www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.vm.RelocateSpec.html
-
'numCPUs'<~Integer> - the number of Virtual CPUs of the Destination VM
-
'numCoresPerSocket'<~Integer> - the number of cores per socket of the Destination VM
-
'memoryMB'<~Integer> - the size of memory of the Destination VM in MB
-
customization_spec<~Hash>: Options are marked as required if you use this customization_spec. As defined pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.Specification.html
-
encryptionKey <~array of bytes> Used to encrypt/decrypt password
-
globalIPSettings expects a hash, REQUIRED
-
identity expects a hash, REQUIRED - either LinuxPrep, Sysprep or SysprepText
-
nicSettingMap expects an array
-
options expects a hash
-
All options can be parsed using a yaml template with cloudinit_to_customspec.rb
OLD Values still supported: This only support cloning and setting DHCP on the first interface
-
'domain'<~String> - REQUIRED This is put into /etc/resolve.conf (we hope)
-
'hostname'<~String> - Hostname of the Guest Os - default is options
-
'hw_utc_clock'<~Boolean> - REQUIRED Is hardware clock UTC? Default true
-
'time_zone'<~String> - REQUIRED Only valid linux options are valid - example: 'America/Denver'
-
'interfaces' <~Array> - interfaces object to apply to
the template when cloning: overrides the network_label, network_adapter_device_key and nic_type attributes
-
'volumes' <~Array> - volumes object to apply to
the template when cloning: this allows to resize the existing disks as well as add or remove them. The resizing is applied only when the size is bigger then the in size in the template
-
-
# File lib/fog/vsphere/requests/compute/vm_clone.rb, line 94 def vm_clone(options = {}) # Option handling options = vm_clone_check_options(options) # Added for people still using options['path'] template_path = options['path'] || options['template_path'] # Options['template_path']<~String> # Added for people still using options['path'] template_path = options['path'] || options['template_path'] # Now find the template itself using the efficient find method vm_mob_ref = get_vm_ref(template_path, options['datacenter']) # Options['dest_folder']<~String> # Grab the destination folder object if it exists else use cloned mach dest_folder_path = options.fetch('dest_folder','/') # default to root path ({dc_name}/vm/) dest_folder = get_raw_vmfolder(dest_folder_path, options['datacenter']) # Options['resource_pool']<~Array> # Now find _a_ resource pool to use for the clone if one is not specified if ( options.key?('resource_pool') && options['resource_pool'].is_a?(Array) && options['resource_pool'].length == 2 && options['resource_pool'][1] != 'Resources') cluster_name = options['resource_pool'][0] pool_name = options['resource_pool'][1] resource_pool = get_raw_resource_pool(pool_name, cluster_name, options['datacenter']) elsif ( options.key?('resource_pool') && options['resource_pool'].is_a?(Array) && options['resource_pool'].length == 2 && options['resource_pool'][1] == 'Resources') cluster_name = options['resource_pool'][0] resource_pool = get_raw_resource_pool(nil, cluster_name, options['datacenter']) elsif ( vm_mob_ref.resourcePool == nil ) # If the template is really a template then there is no associated resource pool, # so we need to find one using the template's parent host or cluster esx_host = vm_mob_ref.collect!('runtime.host')['runtime.host'] # The parent of the ESX host itself is a ComputeResource which has a resourcePool resource_pool = esx_host.parent.resourcePool cluster_name = nil end # If the vm given did return a valid resource pool, default to using it for the clone. # Even if specific pools aren't implemented in this environment, we will still get back # at least the cluster or host we can pass on to the clone task # This catches if resource_pool option is set but comes back nil and if resourcePool is # already set. resource_pool ||= vm_mob_ref.resourcePool.nil? ? esx_host.parent.resourcePool : vm_mob_ref.resourcePool # Options['host']<~String> # The target host for the virtual machine. Optional. if options.key?('host') && !options['host'].empty? && !cluster_name.nil? host = get_raw_host(options['host'], cluster_name, options['datacenter']) else host = nil end # Options['datastore']<~String> # Grab the datastore object if option is set datastore_obj = get_raw_datastore(options['datastore'], options['datacenter']) if options.key?('datastore') # confirm nil if nil or option is not set datastore_obj ||= nil virtual_machine_config_spec = RbVmomi::VIM::VirtualMachineConfigSpec() device_change = [] # fully futured interfaces api: replace the current nics # with the new based on the specification if (options.key?('interfaces') ) if options.key?('network_label') raise ArgumentError, "interfaces option can't be specified together with network_label" end device_change.concat(modify_template_nics_specs(vm_mob_ref, options['interfaces'], options['datacenter'])) elsif options.key?('network_label') device_change << modify_template_nics_simple_spec(options['network_label'], options['nic_type'], options['network_adapter_device_key'], options['datacenter']) end if disks = options['volumes'] device_change.concat(modify_template_volumes_specs(vm_mob_ref, options['volumes'])) end virtual_machine_config_spec.deviceChange = device_change if device_change.any? # Options['numCPUs'] or Options['memoryMB'] # Build up the specification for Hardware, for more details see ____________ # https://github.com/rlane/rbvmomi/blob/master/test/test_serialization.rb # http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.vm.ConfigSpec.html # FIXME: pad this out with the rest of the useful things in VirtualMachineConfigSpec virtual_machine_config_spec.numCPUs = options['numCPUs'] if ( options.key?('numCPUs') ) virtual_machine_config_spec.numCoresPerSocket = options['numCoresPerSocket'] if options.key?('numCoresPerSocket') virtual_machine_config_spec.memoryMB = options['memoryMB'] if ( options.key?('memoryMB') ) virtual_machine_config_spec.cpuHotAddEnabled = options['cpuHotAddEnabled'] if ( options.key?('cpuHotAddEnabled') ) virtual_machine_config_spec.memoryHotAddEnabled = options['memoryHotAddEnabled'] if ( options.key?('memoryHotAddEnabled') ) virtual_machine_config_spec.firmware = options['firmware'] if ( options.key?('firmware') ) virtual_machine_config_spec.extraConfig = extra_config(extra_config: options['extraConfig']) if ( options.key?('extraConfig') ) if @vsphere_rev.to_f >= 5 && options.key?('boot_order') boot_order = options['boot_order'].flat_map do |boot_device| case boot_device.to_sym when :network interfaces = device_change.select do |change| [:edit, :add].include?(change[:operation]) && change[:device].class <= RbVmomi::VIM::VirtualEthernetCard end.map { |change| change[:device] } interfaces.map do |interface| RbVmomi::VIM::VirtualMachineBootOptionsBootableEthernetDevice.new( :deviceKey => interface.key ) end when :disk disks = device_change.select do |change| [:edit, :add].include?(change[:operation]) && change[:device].is_a?(RbVmomi::VIM::VirtualDisk) end.map { |change| change[:device] } disks.map do |disk| RbVmomi::VIM::VirtualMachineBootOptionsBootableDiskDevice.new( :deviceKey => disk.key ) end when :cdrom RbVmomi::VIM::VirtualMachineBootOptionsBootableCdromDevice.new when :floppy RbVmomi::VIM::VirtualMachineBootOptionsBootableFloppyDevice.new end end virtual_machine_config_spec.bootOptions = { :bootOrder => boot_order } end # Options['customization_spec'] # OLD Options still supported # * domain <~String> - *REQUIRED* - Sets the server's domain for customization # * dnsSuffixList <~Array> - Optional - Sets the dns search paths in resolv - Example: ["dev.example.com", "example.com"] # * time_zone <~String> - Required - Only valid linux options are valid - example: 'America/Denver' # * ipsettings <~Hash> - Optional - If not set defaults to dhcp # * ip <~String> - *REQUIRED* Sets the ip address of the VM - Example: 10.0.0.10 # * dnsServerList <~Array> - Optional - Sets the nameservers in resolv - Example: ["10.0.0.2", "10.0.0.3"] # * gateway <~Array> - Optional - Sets the gateway for the interface - Example: ["10.0.0.1"] # * subnetMask <~String> - *REQUIRED* - Set the netmask of the interface - Example: "255.255.255.0" # For other ip settings options see http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.vm.customization.IPSettings.html # # Implement complete customization spec as per https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.Specification.html # * encryptionKey <~Array> - Optional, encryption key used to encypt any encrypted passwords # https://pubs.vmware.com/vsphere-51/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.GlobalIPSettings.html # * globalIPSettings <~Hash> - REQUIRED # * dnsServerList <~Array> - Optional, list of dns servers - Example: ["10.0.0.2", "10.0.0.3"] # * dnsSuffixList <~Array> - Optional, List of name resolution suffixes - Example: ["dev.example.com", "example.com"] # * identity <~Hash> - REQUIRED, Network identity and settings, similar to Microsoft's Sysprep tool. This is a Sysprep, LinuxPrep, or SysprepText object # * Sysprep <~Hash> - Optional, representation of a Windows sysprep.inf answer file. # * guiRunOnce: <~Hash> -Optional, representation of the sysprep GuiRunOnce key # * commandList: <~Array> - REQUIRED, list of commands to run at first user logon, after guest customization. - Example: ["c:\sysprep\runaftersysprep.cmd", "c:\sysprep\installpuppet.ps1"] # * guiUnattended: <~Hash> - REQUIRED, representation of the sysprep GuiUnattended key # * autoLogin: boolean - REQUIRED, Flag to determine whether or not the machine automatically logs on as Administrator. # * autoLogonCount: int - REQUIRED, specifies the number of times the machine should automatically log on as Administrator # * password: <~Hash> - REQUIRED, new administrator password for the machine # * plainText: boolean - REQUIRED, specify whether or not the password is in plain text, rather than encrypted # * value: <~String> - REQUIRED, password string # * timeZone: <~int> - REQUIRED, (see here for values https://msdn.microsoft.com/en-us/library/ms912391(v=winembedded.11).aspx) # * identification: <~Hash> - REQUIRED, representation of the sysprep Identification key # * domainAdmin: <~String> - Optional, domain user account used for authentication if the virtual machine is joining a domain # * domainAdminPassword: <~Hash> - Optional, password for the domain user account used for authentication # * plainText: boolean - REQUIRED, specify whether or not the password is in plain text, rather than encrypted # * value: <~String> - REQUIRED, password string # * joinDomain: <~String> - Optional, The domain that the virtual machine should join. If this value is supplied, then domainAdmin and domainAdminPassword must also be supplied # * joinWorkgroup: <~String> - Optional, The workgroup that the virtual machine should join. # * licenseFilePrintData: <~Hash> - Optional, representation of the sysprep LicenseFilePrintData key # * autoMode: <~String> - REQUIRED, Server licensing mode. Two strings are supported: 'perSeat' or 'perServer' # * autoUsers: <~Int> - Optional, This key is valid only if AutoMode = PerServer. The integer value indicates the number of client licenses # * userData: <~Hash> - REQUIRED, representation of the sysprep UserData key # * computerName: <~String> - REQUIRED, The computer name of the (Windows) virtual machine. Will be truncates to 15 characters # * fullName: <~String> - REQUIRED, User's full name # * orgName: <~String> - REQUIRED, User's organization # * productId: <~String> - REQUIRED, serial number for os, ignored if using volume licensed instance # * LinuxPrep: <~Hash> - Optional, contains machine-wide settings (note the uppercase P) # * domain: <~String> - REQUIRED, The fully qualified domain name. # * hostName: <~String> - REQUIRED, the network host name # * hwClockUTC: <~Boolean> - Optional, Specifies whether the hardware clock is in UTC or local time # * timeZone: <~String> - Optional, Case sensistive timezone, valid values can be found at https://pubs.vmware.com/vsphere-51/topic/com.vmware.wssdk.apiref.doc/timezone.html # * SysprepText: <~Hash> - Optional, alternate way to specify the sysprep.inf answer file. # * value: <~String> - REQUIRED, Text for the sysprep.inf answer file. # * nicSettingMap: <~Array> - Optional, IP settings that are specific to a particular virtual network adapter # * Each item in array: # * adapter: <~Hash> - REQUIRED, IP settings for the associated virtual network adapter # * dnsDomain: <~String> - Optional, DNS domain suffix for adapter # * dnsServerList: <~Array> - Optional, list of dns server ip addresses - Example: ["10.0.0.2", "10.0.0.3"] # * gateway: <~Array> - Optional, list of gateways - Example: ["10.0.0.2", "10.0.0.3"] # * ip: <~String> - Optional, but required if static IP # * ipV6Spec: <~Hash> - Optional, IPv^ settings # * ipAddress: <~String> - Optional, but required if setting static IP # * gateway: <~Array> - Optional, list of ipv6 gateways # * netBIOS: <~String> - Optional, NetBIOS settings, if supplied must be one of: disableNetBIOS','enableNetBIOS','enableNetBIOSViaDhcp' # * primaryWINS: <~String> - Optional, IP address of primary WINS server # * secondaryWINS: <~String> - Optional, IP address of secondary WINS server # * subnetMask: <~String> - Optional, subnet mask for adapter # * macAddress: <~String> - Optional, MAC address of adapter being customized. This cannot be set by the client # * options: <~Hash> Optional operations, currently only win options have any value # * changeSID: <~Boolean> - REQUIRED, The customization process should modify the machine's security identifier # * deleteAccounts: <~Boolean> - REQUIRED, If deleteAccounts is true, then all user accounts are removed from the system # * reboot: <~String> - Optional, (defaults to reboot), Action to be taken after running sysprep, must be one of: 'noreboot', 'reboot', 'shutdown' # if ( options.key?('customization_spec') ) custom_spec = options['customization_spec'] # backwards compatablity if custom_spec.key?('domain') # doing this means the old options quash any new ones passed as well... might not be the best way to do it? # any 'old' options overwrite the following: # - custom_spec['identity']['LinuxPrep'] # - custom_spec['globalIPSettings['['dnsServerList'] # - custom_spec['globalIPSettings']['dnsSuffixList'] # - custom_spec['nicSettingMap'][0]['adapter']['ip'] # - custom_spec['nicSettingMap'][0]['adapter']['gateway'] # - custom_spec['nicSettingMap'][0]['adapter']['subnetMask'] # - custom_spec['nicSettingMap'][0]['adapter']['dnsDomain'] # - custom_spec['nicSettingMap'][0]['adapter']['dnsServerList'] # # we can assume old parameters being passed cust_hostname = custom_spec['hostname'] || options['name'] custom_spec['identity'] = Hash.new unless custom_spec.key?('identity') custom_spec['identity']['LinuxPrep'] = {"domain" => custom_spec['domain'], "hostName" => cust_hostname, "timeZone" => custom_spec['time_zone']} if custom_spec.key?('ipsettings') custom_spec['globalIPSettings']=Hash.new unless custom_spec.key?('globalIPSettings') custom_spec['globalIPSettings']['dnsServerList'] = custom_spec['ipsettings']['dnsServerList'] if custom_spec['ipsettings'].key?('dnsServerList') custom_spec['globalIPSettings']['dnsSuffixList'] = custom_spec['dnsSuffixList'] || [custom_spec['domain']] if ( custom_spec['dnsSuffixList'] || custom_spec['domain']) if (custom_spec['ipsettings'].key?('ip') or custom_spec['ipsettings'].key?('gateway') or custom_spec['ipsettings'].key?('subnetMask') or custom_spec['ipsettings'].key?('domain') or custom_spec['ipsettings'].key?('dnsServerList')) if custom_spec['ipsettings'].key?('ip') and !custom_spec["ipsettings"].key?("subnetMask") raise ArgumentError, "subnetMask is required for static ip" end custom_spec['nicSettingMap']=Array.new unless custom_spec.key?('nicSettingMap') custom_spec['nicSettingMap'][0]=Hash.new unless custom_spec['nicSettingMap'].length > 0 custom_spec['nicSettingMap'][0]['adapter']=Hash.new unless custom_spec['nicSettingMap'][0].key?('adapter') custom_spec['nicSettingMap'][0]['adapter']['ip'] = custom_spec['ipsettings']['ip'] if custom_spec['ipsettings'].key?('ip') custom_spec['nicSettingMap'][0]['adapter']['gateway'] = custom_spec['ipsettings']['gateway'] if custom_spec['ipsettings'].key?('gateway') custom_spec['nicSettingMap'][0]['adapter']['subnetMask'] = custom_spec['ipsettings']['subnetMask'] if custom_spec['ipsettings'].key?('subnetMask') custom_spec['nicSettingMap'][0]['adapter']['dnsDomain'] = custom_spec['ipsettings']['domain'] if custom_spec['ipsettings'].key?('domain') custom_spec['nicSettingMap'][0]['adapter']['dnsServerList'] = custom_spec['ipsettings']['dnsServerList'] if custom_spec['ipsettings'].key?('dnsServerList') end end end ### End of backwards compatability ## requirements check here ## raise ArgumentError, "globalIPSettings are required when using Customization Spec" unless custom_spec.key?('globalIPSettings') raise ArgumentError, "identity is required when using Customization Spec" unless custom_spec.key?('identity') # encryptionKey custom_encryptionKey = custom_spec['encryptionKey'] if custom_spec.key?('encryptionKey') custom_encryptionKey ||= nil # globalIPSettings # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.GlobalIPSettings.html custom_globalIPSettings = RbVmomi::VIM::CustomizationGlobalIPSettings.new() custom_globalIPSettings.dnsServerList = custom_spec['globalIPSettings']['dnsServerList'] if custom_spec['globalIPSettings'].key?("dnsServerList") custom_globalIPSettings.dnsSuffixList = custom_spec['globalIPSettings']['dnsSuffixList'] if custom_spec['globalIPSettings'].key?("dnsSuffixList") # identity # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.IdentitySettings.html # Accepts the 3 supported CustomizationIdentitySettings Types: # 1. CustomizationLinuxPrep (LinuxPrep) - note the uppercase P # 2. CustomizationSysprep (Sysprep) # 3. CustomizationSysprepText (SysprepText) # At least one of these is required # identity = custom_spec['identity'] if identity.key?("LinuxPrep") # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.LinuxPrep.html # Fields: # * domain: string **REQUIRED** # * hostName: string (CustomizationName) **REQUIRED** Will use options['name'] if not provided. # * hwClockUTC: boolean # * timeZone: string (https://pubs.vmware.com/vsphere-55/topic/com.vmware.wssdk.apiref.doc/timezone.html) raise ArgumentError, "domain is required when using LinuxPrep identity" unless identity['LinuxPrep'].key?('domain') custom_identity = RbVmomi::VIM::CustomizationLinuxPrep(:domain => identity['LinuxPrep']['domain']) cust_hostname = RbVmomi::VIM::CustomizationFixedName(:name => identity['LinuxPrep']['hostName']) if identity['LinuxPrep'].key?('hostName') cust_hostname ||= RbVmomi::VIM::CustomizationFixedName(:name => options['name']) custom_identity.hostName = cust_hostname custom_identity.hwClockUTC = identity['LinuxPrep']['hwClockUTC'] if identity['LinuxPrep'].key?('hwClockUTC') custom_identity.timeZone = identity['LinuxPrep']['timeZone'] if identity['LinuxPrep'].key?('timeZone') elsif identity.key?("Sysprep") # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.Sysprep.html # Fields: # * guiRunOnce: CustomizationGuiRunOnce # * guiUnattended: CustomizationGuiUnattended **REQUIRED** # * identification: CustomizationIdentification **REQUIRED** # * licenseFilePrintData: CustomizationLicenseFilePrintData # * userData: CustomizationUserData **REQUIRED** # raise ArgumentError, "guiUnattended is required when using Sysprep identity" unless identity['Sysprep'].key?('guiUnattended') raise ArgumentError, "identification is required when using Sysprep identity" unless identity['Sysprep'].key?('identification') raise ArgumentError, "userData is required when using Sysprep identity" unless identity['Sysprep'].key?('userData') if identity['Sysprep']['guiRunOnce'] # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.GuiRunOnce.html # Fields: # * commandList: array of string **REQUIRED*** # raise ArgumentError, "commandList is required when using Sysprep identity and guiRunOnce" unless identity['Sysprep']['guiRunOnce'].key?('commandList') cust_guirunonce = RbVmomi::VIM.CustomizationGuiRunOnce( :commandList => identity['Sysprep']['guiRunOnce']['commandList'] ) end # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.GuiUnattended.html # Fields: # * autoLogin: boolean **REQUIRED** # * autoLogonCount: int **REQUIRED** # * timeZone: int (see here for values https://msdn.microsoft.com/en-us/library/ms912391(v=winembedded.11).aspx) **REQUIRED** # * password: CustomizationPassword raise ArgumentError, "guiUnattended->autoLogon is required when using Sysprep identity" unless identity['Sysprep']['guiUnattended'].key?('autoLogon') raise ArgumentError, "guiUnattended->autoLogonCount is required when using Sysprep identity" unless identity['Sysprep']['guiUnattended'].key?('autoLogonCount') raise ArgumentError, "guiUnattended->timeZone is required when using Sysprep identity" unless identity['Sysprep']['guiUnattended'].key?('timeZone') custom_guiUnattended = RbVmomi::VIM.CustomizationGuiUnattended( :autoLogon => identity['Sysprep']['guiUnattended']['autoLogon'], :autoLogonCount => identity['Sysprep']['guiUnattended']['autoLogonCount'], :timeZone => identity['Sysprep']['guiUnattended']['timeZone'] ) if identity['Sysprep']['guiUnattended']['password'] # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.Password.html # Fields: # * plainText: boolean **REQUIRED** # * value: string **REQUIRED** raise ArgumentError, "guiUnattended->password->plainText is required when using Sysprep identity and guiUnattended -> password" unless identity['Sysprep']['guiUnattended']['password'].key?('plainText') raise ArgumentError, "guiUnattended->password->value is required when using Sysprep identity and guiUnattended -> password" unless identity['Sysprep']['guiUnattended']['password'].key?('value') custom_guiUnattended.password = RbVmomi::VIM.CustomizationPassword( :plainText => identity['Sysprep']['guiUnattended']['password']['plainText'], :value => identity['Sysprep']['guiUnattended']['password']['value'] ) end # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.Identification.html # Fields: # * domainAdmin: string # * domainAdminPassword: CustomizationPassword # * joinDomain: string *If supplied domainAdmin and domainAdminPassword must be set # * joinWorkgroup: string *If supplied, joinDomain, domainAdmin and domainAdminPassword will be ignored custom_identification = RbVmomi::VIM.CustomizationIdentification() if identity['Sysprep']['identification'].key?('joinWorkgroup') custom_identification.joinWorkgroup = identity['Sysprep']['identification']['joinWorkgroup'] elsif identity['Sysprep']['identification'].key?('joinDomain') raise ArgumentError, "identification->domainAdmin is required when using Sysprep identity and identification -> joinDomain" unless identity['Sysprep']['identification'].key?('domainAdmin') raise ArgumentError, "identification->domainAdminPassword is required when using Sysprep identity and identification -> joinDomain" unless identity['Sysprep']['identification'].key?('domainAdmin') raise ArgumentError, "identification->domainAdminPassword->plainText is required when using Sysprep identity and identification -> joinDomain" unless identity['Sysprep']['identification']['domainAdminPassword'].key?('plainText') raise ArgumentError, "identification->domainAdminPassword->value is required when using Sysprep identity and identification -> joinDomain" unless identity['Sysprep']['identification']['domainAdminPassword'].key?('value') custom_identification.joinDomain = identity['Sysprep']['identification']['joinDomain'] custom_identification.domainAdmin = identity['Sysprep']['identification']['domainAdmin'] # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.Password.html # Fields: # * plainText: boolean **REQUIRED** # * value: string **REQUIRED** custom_identification.domainAdminPassword = RbVmomi::VIM.CustomizationPassword( :plainText => identity['Sysprep']['identification']['domainAdminPassword']['plainText'], :value => identity['Sysprep']['identification']['domainAdminPassword']['value'] ) else raise ArgumentError, "No valid Indentification found, valid values are 'joinWorkgroup' and 'joinDomain'" end if identity['Sysprep'].key?('licenseFilePrintData') # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.LicenseFilePrintData.html # Fields: # * autoMode: string (CustomizationLicenseDataMode) ** REQUIRED **, valid strings are: 'perSeat' or 'perServer' # * autoUsers: int (valid only if AutoMode = PerServer) raise ArgumentError, "licenseFilePrintData->autoMode is required when using Sysprep identity and licenseFilePrintData" unless identity['Sysprep']['licenseFilePrintData'].key?('autoMode') raise ArgumentError, "Unsupported autoMode, supported modes are : 'perSeat' or 'perServer'" unless ['perSeat', 'perServer'].include? identity['Sysprep']['licenseFilePrintData']['autoMode'] custom_licenseFilePrintData = RbVmomi::VIM.CustomizationLicenseFilePrintData( :autoMode => RbVmomi::VIM.CustomizationLicenseDataMode(identity['Sysprep']['licenseFilePrintData']['autoMode']) ) if identity['Sysprep']['licenseFilePrintData'].key?('autoUsers') custom_licenseFilePrintData.autoUsers = identity['Sysprep']['licenseFilePrintData']['autoUsers'] if identity['Sysprep']['licenseFilePrintData']['autoMode'] == "PerServer" end end # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.UserData.html # Fields: # * computerName: string (CustomizationFixedName) **REQUIRED** # * fullName: string **REQUIRED** # * orgName: string **REQUIRED** # * productID: string **REQUIRED** raise ArgumentError, "userData->computerName is required when using Sysprep identity" unless identity['Sysprep']['userData'].key?('computerName') raise ArgumentError, "userData->fullName is required when using Sysprep identity" unless identity['Sysprep']['userData'].key?('fullName') raise ArgumentError, "userData->orgName is required when using Sysprep identity" unless identity['Sysprep']['userData'].key?('orgName') raise ArgumentError, "userData->productId is required when using Sysprep identity" unless identity['Sysprep']['userData'].key?('productId') custom_userData = RbVmomi::VIM.CustomizationUserData( :fullName => identity['Sysprep']['userData']['fullName'], :orgName => identity['Sysprep']['userData']['orgName'], :productId => identity['Sysprep']['userData']['productId'], :computerName => RbVmomi::VIM.CustomizationFixedName(:name => identity['Sysprep']['userData']['computerName']) ) custom_identity = RbVmomi::VIM::CustomizationSysprep( :guiUnattended => custom_guiUnattended, :identification => custom_identification, :userData => custom_userData ) custom_identity.guiRunOnce = cust_guirunonce if defined?(cust_guirunonce) custom_identity.licenseFilePrintData = custom_licenseFilePrintData if defined?(custom_licenseFilePrintData) elsif identity.key?("SysprepText") # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.SysprepText.html # Fields: # * value: string **REQUIRED** raise ArgumentError, "SysprepText -> value is required when using SysprepText identity" unless identity['SysprepText'].key?('value') custom_identity = RbVmomi::VIM::CustomizationSysprepText(:value => identity['SysprepText']['value']) else raise ArgumentError, "At least one of the following valid identities must be supplied: LinuxPrep, Sysprep, SysprepText" end if custom_spec.key?("nicSettingMap") # custom_spec['nicSettingMap'] is an array of adapater mappings: # custom_spec['nicSettingMap'][0]['macAddress'] # custom_spec['nicSettingMap'][0]['adapter']['ip'] #https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.AdapterMapping.html # Fields: # * adapter: CustomizationIPSettings **REQUIRED** # * macAddress: string raise ArgumentError, "At least one nicSettingMap is required when using nicSettingMap" unless custom_spec['nicSettingMap'].length > 0 raise ArgumentError, "Adapter is required when using nicSettingMap" unless custom_spec['nicSettingMap'][0].key?('adapter') custom_nicSettingMap = [] # need to go through array here for each apapter custom_spec['nicSettingMap'].each do | nic | # https://pubs.vmware.com/vsphere-55/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvim.vm.customization.IPSettings.html # Fields: # * dnsDomain: string # * gateway: array of string # * ip: CustomizationIpGenerator (string) **REQUIRED IF Assigning Static IP*** # * ipV6Spec: CustomizationIPSettingsIpV6AddressSpec # * netBIOS: CustomizationNetBIOSMode (string) # * primaryWINS: string # * secondaryWINS: string # * subnetMask: string - Required if assigning static IP if nic['adapter'].key?('ip') raise ArgumentError, "SubnetMask is required when assigning static IP when using nicSettingMap -> Adapter" unless nic['adapter'].key?('subnetMask') custom_ip = RbVmomi::VIM.CustomizationFixedIp(:ipAddress => nic['adapter']['ip']) else custom_ip = RbVmomi::VIM::CustomizationDhcpIpGenerator.new() end custom_adapter = RbVmomi::VIM.CustomizationIPSettings(:ip => custom_ip) custom_adapter.dnsDomain = nic['adapter']['dnsDomain'] if nic['adapter'].key?('dnsDomain') custom_adapter.dnsServerList = nic['adapter']['dnsServerList'] if nic['adapter'].key?('dnsServerList') custom_adapter.gateway = nic['adapter']['gateway'] if nic['adapter'].key?('gateway') if nic['adapter'].key?('ipV6Spec') # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.IPSettings.IpV6AddressSpec.html # Fields: # * gateway: array of string # * ip: CustomizationIpV6Generator[] **Required if setting static IP ** if nic['adapter']['ipV6Spec'].key?('ipAddress') raise ArgumentError, "SubnetMask is required when assigning static IPv6 when using nicSettingMap -> Adapter -> ipV6Spec" unless nic['adapter']['ipV6Spec'].key?('subnetMask') # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.FixedIpV6.html # * ipAddress: string **REQUIRED** # * subnetMask: int **REQUIRED** custom_ipv6 = RbVmomi::VIM.CustomizationFixedIpV6( :ipAddress => nic['adapter']['ipV6Spec']['ipAddress'], :subnetMask => nic['adapter']['ipV6Spec']['subnetMask'] ) else custom_ipv6 = RbVmomi::VIM::CustomizationDhcpIpV6Generator.new() end custom_ipv6Spec = RbVmomi::VIM.CustomizationIPSettingsIpV6AddressSpec(:ip => custom_ipv6) custom_ipv6Spec.gateway = nic['adapter']['ipV6Spec']['gateway'] if nic['adapter']['ipV6Spec'].key?('gateway') custom_adapter.ipV6Spec = custom_ipv6Spec end if nic['adapter'].key?('netBIOS') # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.IPSettings.NetBIOSMode.html # Fields: # netBIOS: string matching: 'disableNetBIOS','enableNetBIOS' or 'enableNetBIOSViaDhcp' ** REQUIRED ** # raise ArgumentError, "Unsupported NetBIOSMode, supported modes are : 'disableNetBIOS','enableNetBIOS' or 'enableNetBIOSViaDhcp'" unless ['disableNetBIOS','enableNetBIOS','enableNetBIOSViaDhcp'].include? nic['adapter']['netBIOS'] custom_adapter.netBIOS = RbVmomi::VIM.CustomizationNetBIOSMode(nic['adapter']['netBIOS']) end custom_adapter.primaryWINS = nic['adapter']['primaryWINS'] if nic['adapter'].key?('primaryWINS') custom_adapter.secondaryWINS = nic['adapter']['secondaryWINS'] if nic['adapter'].key?('secondaryWINS') custom_adapter.subnetMask = nic['adapter']['subnetMask'] if nic['adapter'].key?('subnetMask') custom_adapter_mapping = RbVmomi::VIM::CustomizationAdapterMapping(:adapter => custom_adapter) custom_adapter_mapping.macAddress = nic['macAddress'] if nic.key?('macAddress') # build the adapters array custom_nicSettingMap << custom_adapter_mapping end end if custom_spec.key?("options") # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.Options.html # this currently doesn't have any Linux options, just windows # Fields: # * changeSID: boolean **REQUIRED** # * deleteAccounts: boolean **REQUIRED** **note deleteAccounts is deprecated as of VI API 2.5 so can be ignored # * reboot: CustomizationSysprepRebootOption: (string) one of following 'noreboot', reboot' or 'shutdown' (defaults to reboot) raise ArgumentError, "changeSID id required when using Windows Options" unless custom_spec['options'].key?('changeSID') raise ArgumentError, "deleteAccounts id required when using Windows Options" unless custom_spec['options'].key?('deleteAccounts') custom_options = RbVmomi::VIM::CustomizationWinOptions( :changeSID => custom_spec['options']['changeSID'], :deleteAccounts => custom_spec['options']['deleteAccounts'] ) if custom_spec['options'].key?('reboot') raise ArgumentError, "Unsupported reboot option, supported options are : 'noreboot', 'reboot' or 'shutdown'" unless ['noreboot','reboot','shutdown'].include? custom_spec['options']['reboot'] custom_options.reboot = RBVmomi::VIM.CustomizationSysprepRebootOption(custom_spec['options']['reboot']) end end custom_options ||=nil # https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.Specification.html customization_spec = RbVmomi::VIM::CustomizationSpec( :globalIPSettings => custom_globalIPSettings, :identity => custom_identity ) customization_spec.encryptionKey = custom_encryptionKey if defined?(custom_encryptionKey) customization_spec.nicSettingMap = custom_nicSettingMap if defined?(custom_nicSettingMap) customization_spec.options = custom_options if defined?(custom_options) end customization_spec ||= nil relocation_spec=nil if ( options['linked_clone'] ) # Storage DRS does not support vSphere linked clones. # http://www.vmware.com/files/pdf/techpaper/vsphere-storage-drs-interoperability.pdf raise ArgumentError, "linked clones are not supported on storage pods" unless options.key?('storage_pod') # cribbed heavily from the rbvmomi clone_vm.rb # this chunk of code reconfigures the disk of the clone source to be read only, # and then creates a delta disk on top of that, this is required by the API in order to create # linked clondes disks = vm_mob_ref.config.hardware.device.select do |vm_device| vm_device.class == RbVmomi::VIM::VirtualDisk end disks.select{|vm_device| vm_device.backing.parent == nil}.each do |disk| disk_spec = { :deviceChange => [ { :operation => :remove, :device => disk }, { :operation => :add, :fileOperation => :create, :device => disk.dup.tap{|disk_backing| disk_backing.backing = disk_backing.backing.dup; disk_backing.backing.fileName = "[#{disk.backing.datastore.name}]"; disk_backing.backing.parent = disk.backing } } ] } vm_mob_ref.ReconfigVM_Task(:spec => disk_spec).wait_for_completion end # Next, create a Relocation Spec instance relocation_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(:datastore => datastore_obj, :pool => resource_pool, :host => host, :diskMoveType => :moveChildMostDiskBacking) else relocation_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => resource_pool, :host => host, :transform => options['transform'] || 'sparse') unless options.key?('storage_pod') and datastore_obj.nil? relocation_spec[:datastore] = datastore_obj end end # relocate templates is not supported by fog-vsphere when vm is cloned on a storage pod unless options.key?('storage_pod') relocation_spec[:disk] = relocate_template_volumes_specs(vm_mob_ref, options['volumes'], options['datacenter']) end # And the clone specification clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(:location => relocation_spec, :config => virtual_machine_config_spec, :customization => customization_spec, :powerOn => options.key?('power_on') ? options['power_on'] : true, :template => false) # Perform the actual Clone Task # Clone VM on a storage pod if options.key?('storage_pod') and !options['storage_pod'].nil? raise ArgumentError, "need to use at least vsphere revision 5.0 or greater to use storage pods" unless @vsphere_rev.to_f >= 5 pod_spec = RbVmomi::VIM::StorageDrsPodSelectionSpec.new( :storagePod => get_raw_storage_pod(options['storage_pod'], options['datacenter']), ) storage_spec = RbVmomi::VIM::StoragePlacementSpec.new( :type => 'clone', :folder => dest_folder, :resourcePool => resource_pool, :podSelectionSpec => pod_spec, :cloneSpec => clone_spec, :cloneName => options['name'], :vm => vm_mob_ref, ) srm = connection.serviceContent.storageResourceManager result = srm.RecommendDatastores(:storageSpec => storage_spec) # if result array contains recommendation, we can apply it if key = result.recommendations.first.key task = srm.ApplyStorageDrsRecommendation_Task(:key => [key]) if options.fetch('wait', true) then result = task.wait_for_completion new_vm = result.vm else new_vm = nil Fog.wait_for(150, 15) { begin new_vm = dest_folder.find(options['name'], RbVmomi::VIM::VirtualMachine) or raise Fog::Vsphere::Errors::NotFound rescue Fog::Vsphere::Errors::NotFound new_vm = nil end } raise Fog::Vsphere::Errors::NotFound unless new_vm end end else task = vm_mob_ref.CloneVM_Task(:folder => dest_folder, :name => options['name'], :spec => clone_spec) # Waiting for the VM to complete allows us to get the VirtulMachine # object of the new machine when it's done. It is HIGHLY recommended # to set 'wait' => true if your app wants to wait. Otherwise, you're # going to have to reload the server model over and over which # generates a lot of time consuming API calls to vmware. if options.fetch('wait', true) then # REVISIT: It would be awesome to call a block passed to this # request to notify the application how far along in the process we # are. I'm thinking of updating a progress bar, etc... new_vm = task.wait_for_completion else new_vm = nil Fog.wait_for(150, 15) { begin new_vm = dest_folder.find(options['name'], RbVmomi::VIM::VirtualMachine) or raise Fog::Vsphere::Errors::NotFound rescue Fog::Vsphere::Errors::NotFound new_vm = nil end } raise Fog::Vsphere::Errors::NotFound unless new_vm end end # Return hash { 'vm_ref' => new_vm ? new_vm._ref : nil, 'new_vm' => new_vm ? convert_vm_mob_ref_to_attr_hash(new_vm) : nil, 'task_ref' => task._ref } end
# File lib/fog/vsphere/requests/compute/vm_config_vnc.rb, line 5 def vm_config_vnc(options = { }) raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' search_filter = { :uuid => options['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = connection.searchIndex.FindAllByUuid(search_filter).first task = vm_mob_ref.ReconfigVM_Task(:spec => { :extraConfig => [ { :key => 'RemoteDisplay.vnc.enabled', :value => options[:enabled] ? 'true' : 'false' }, { :key => 'RemoteDisplay.vnc.password', :value => options[:password].to_s }, { :key => 'RemoteDisplay.vnc.port', :value => options[:port].to_s || '5910' } ] }) task.wait_for_completion { 'task_state' => task.info.state } end
# File lib/fog/vsphere/requests/compute/vm_destroy.rb, line 5 def vm_destroy(options = {}) raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' vm_mob_ref = get_vm_ref(options['instance_uuid']) task = vm_mob_ref.Destroy_Task task.wait_for_completion { 'task_state' => task.info.state } end
NOTE: you must be using vsphere_rev 5.0 or greater to use this functionality e.g. Fog::Compute.new(provider: “vsphere”, vsphere_rev: “5.5”, etc)
-
options<~Hash>:
-
'instance_uuid'<~String> - REQUIRED the instance uuid you would like to operate on
-
'command'<~String> REQUIRED the command to execute
-
'args'<~String> arguments to pass the command
-
'working_dir'<~String> path to the working directory
-
'user'<~String> REQUIRED the ssh username you would like to login as
-
'password'<~String> REQUIRED the ssh password for the user you would like to log in as
-
# File lib/fog/vsphere/requests/compute/vm_execute.rb, line 14 def vm_execute(options = {}) raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' raise ArgumentError, "command is a required parameter" unless options.key? 'command' raise ArgumentError, "user is a required parameter" unless options.key? 'user' raise ArgumentError, "password is a required parameter" unless options.key? 'password' search_filter = { :uuid => options['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = connection.searchIndex.FindAllByUuid(search_filter).first auth = RbVmomi::VIM::NamePasswordAuthentication(:interactiveSession => false, :username => options['user'], :password => options['password']) spec = RbVmomi::VIM::GuestProgramSpec(:programPath => options['command'], :arguments => options['args'], :workingDirectory => options['working_dir']) gom = connection.serviceContent.guestOperationsManager gom.processManager.StartProgramInGuest(:vm => vm_mob_ref, :auth => auth, :spec => spec) end
return a hash of VNC attributes required to view the console
# File lib/fog/vsphere/requests/compute/vm_config_vnc.rb, line 22 def vm_get_vnc uuid search_filter = { :uuid => uuid, 'vmSearch' => true, 'instanceUuid' => true } vm = connection.searchIndex.FindAllByUuid(search_filter).first Hash[vm.config.extraConfig.map do |config| if config.key =~ /^RemoteDisplay\.vnc\.(\w+)$/ [$1.to_sym, config.value] end end.compact] end
# File lib/fog/vsphere/requests/compute/vm_migrate.rb, line 5 def vm_migrate(options = {}) #priority is the only required option, and it has a sane default option. priority = options['priority'].nil? ? 'defaultPriority' : options["priority"] raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' # Find the VM Object search_filter = { :uuid => options['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = connection.searchIndex.FindAllByUuid(search_filter).first unless vm_mob_ref.kind_of? RbVmomi::VIM::VirtualMachine raise Fog::Vsphere::Errors::NotFound, "Could not find VirtualMachine with instance uuid #{options['instance_uuid']}" end options['host'] = get_raw_host(options['host'], options['cluster'], options['datacenter']) if options['host'] task_options = {:pool => options['pool'], :host => options['host'], :state => options['state']} if options['check'] checker = connection.serviceContent.vmProvisioningChecker task = checker.CheckMigrate_Task(task_options.merge(:vm => vm_mob_ref)) task.wait_for_completion {'error' => task.info.result[0].error, 'warning' => task.info.result[0].warning} else task = vm_mob_ref.MigrateVM_Task(task_options.merge(:priority => "#{priority}")) task.wait_for_completion { 'task_state' => task.info.state } end end
# File lib/fog/vsphere/requests/compute/vm_power_off.rb, line 5 def vm_power_off(options = {}) options = { 'force' => false }.merge(options) raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' search_filter = { :uuid => options['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = connection.searchIndex.FindAllByUuid(search_filter).first if options['force'] then task = vm_mob_ref.PowerOffVM_Task task.wait_for_completion { 'task_state' => task.info.result, 'power_off_type' => 'cut_power' } else vm_mob_ref.ShutdownGuest { 'task_state' => "running", 'power_off_type' => 'shutdown_guest', } end end
# File lib/fog/vsphere/requests/compute/vm_power_on.rb, line 5 def vm_power_on(options = {}) raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' search_filter = { :uuid => options['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = connection.searchIndex.FindAllByUuid(search_filter).first task = vm_mob_ref.PowerOnVM_Task task.wait_for_completion # 'success', 'running', 'queued', 'error' { 'task_state' => task.info.state } end
# File lib/fog/vsphere/requests/compute/vm_reboot.rb, line 5 def vm_reboot(options = {}) options = { 'force' => false }.merge(options) raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' search_filter = { :uuid => options['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = connection.searchIndex.FindAllByUuid(search_filter).first if options['force'] then task = vm_mob_ref.ResetVM_Task task.wait_for_completion { 'task_state' => task.info.result, 'reboot_type' => 'reset_power' } else vm_mob_ref.RebootGuest { 'task_state' => "running", 'reboot_type' => 'reboot_guest' } end end
# File lib/fog/vsphere/requests/compute/vm_reconfig_cdrom.rb, line 5 def vm_reconfig_cdrom(options = {}) raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' # Attach iso / disattach if options.has_key?('iso') raise ArgumentError, "datastore is a required parameter" unless options.key? 'datastore' backing = RbVmomi::VIM::VirtualCdromIsoBackingInfo( fileName: "[#{options['datastore']}] #{options['iso']}" ) else backing = RbVmomi::VIM::VirtualCdromRemoteAtapiBackingInfo(deviceName: '') end cdrom_obj = get_vm_ref(options['instance_uuid']).config.hardware.device.grep(RbVmomi::VIM::VirtualCdrom).first hardware_spec = { deviceChange: [{ operation: :edit, device: RbVmomi::VIM::VirtualCdrom( backing: backing, key: cdrom_obj.key, controllerKey: cdrom_obj.controllerKey, connectable: RbVmomi::VIM::VirtualDeviceConnectInfo( startConnected: options['start_connected'] || false, connected: options['connected'] || false, allowGuestControl: options['allow_guest_control'] || true, ) ) }] } vm_reconfig_hardware('instance_uuid' => options['instance_uuid'], 'hardware_spec' => hardware_spec ) end
# File lib/fog/vsphere/requests/compute/vm_reconfig_cpus.rb, line 5 def vm_reconfig_cpus(options = {}) raise ArgumentError, "cpus is a required parameter" unless options.key? 'cpus' raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' hardware_spec={'numCPUs' => options['cpus'], 'numCoresPerSocket' => options['corespersocket']} vm_reconfig_hardware('instance_uuid' => options['instance_uuid'], 'hardware_spec' => hardware_spec ) end
# File lib/fog/vsphere/requests/compute/vm_reconfig_hardware.rb, line 5 def vm_reconfig_hardware(options = {}) raise ArgumentError, "hardware_spec is a required parameter" unless options.key? 'hardware_spec' raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' vm_mob_ref = get_vm_ref(options['instance_uuid']) task = vm_mob_ref.ReconfigVM_Task(:spec => RbVmomi::VIM.VirtualMachineConfigSpec(options['hardware_spec'])) task.wait_for_completion { 'task_state' => task.info.state } end
# File lib/fog/vsphere/requests/compute/vm_reconfig_memory.rb, line 5 def vm_reconfig_memory(options = {}) raise ArgumentError, "memory is a required parameter" unless options.key? 'memory' raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' hardware_spec={'memoryMB' => options['memory']} vm_reconfig_hardware('instance_uuid' => options['instance_uuid'], 'hardware_spec' => hardware_spec ) end
# File lib/fog/vsphere/requests/compute/vm_reconfig_volumes.rb, line 5 def vm_reconfig_volumes(options = {}) raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' raise ArgumentError, "volumes is a required parameter" unless options.key? 'volumes' hardware_spec = { deviceChange: [] } options['volumes'].each do |volume| hardware_spec[:deviceChange].push(create_disk(volume, :edit, filename: volume.filename)) end vm_reconfig_hardware('instance_uuid' => options['instance_uuid'], 'hardware_spec' => hardware_spec ) end
Clones a VM from a template or existing machine on your vSphere Server.
Parameters¶ ↑
-
options<~Hash>:
-
'instance_uuid'<~String> - REQUIRED VM to relocate
-
'host'<~String> - name of host which will run the VM.
-
'pool'<~String> - name of pool which the VM should be
attached.
-
'disks'<~Array> - disks to relocate. Each disk is a
hash with diskId wich is key attribute of volume, and datastore to relocate to.
-
# File lib/fog/vsphere/requests/compute/vm_relocate.rb, line 17 def vm_relocate(options = {}) raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' # Find the VM Object search_filter = { :uuid => options['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = connection.searchIndex.FindAllByUuid(search_filter).first unless vm_mob_ref.kind_of? RbVmomi::VIM::VirtualMachine raise Fog::Vsphere::Errors::NotFound, "Could not find VirtualMachine with instance uuid #{options['instance_uuid']}" end options['host'] = get_raw_host(options['host'], options['cluster'], options['datacenter']) if options['host'] if options['disks'] options['disks'] = options['disks'].map do |disk| disk['datastore'] = get_raw_datastore(disk['datastore'], nil) RbVmomi::VIM::VirtualMachineRelocateSpecDiskLocator(disk) end end spec = RbVmomi::VIM::VirtualMachineRelocateSpec( :pool => options['pool'], :host => options['host'], :disk => options['disks'] ) task = vm_mob_ref.RelocateVM_Task(:spec => spec, :priority => options["priority"]) task.wait_for_completion { 'task_state' => task.info.state } end
# File lib/fog/vsphere/requests/compute/vm_remove_snapshot.rb, line 5 def vm_remove_snapshot(vm_id, snapshot_id, remove_children = false) vm = servers.get(vm_id) snapshot = vm.snapshots.get(snapshot_id).mo_ref task = snapshot.RemoveSnapshot_Task(:removeChildren => remove_children) task.wait_for_completion { 'task_state' => task.info.state, 'was_cancelled' => task.info.cancelled } end
# File lib/fog/vsphere/requests/compute/vm_rename.rb, line 5 def vm_rename(options = {}) raise ArgumentError, "name is a required parameter" unless options.key? 'name' raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' vm_mob_ref = get_vm_ref(options['instance_uuid']) task = vm_mob_ref.Rename_Task(:newName => options['name']) task.wait_for_completion { 'task_state' => task.info.state } end
# File lib/fog/vsphere/requests/compute/vm_revert_snapshot.rb, line 5 def vm_revert_snapshot(vm_id, snapshot_id) vm = servers.get(vm_id) snapshot = vm.snapshots.get(snapshot_id).mo_ref task = snapshot.RevertToSnapshot_Task task.wait_for_completion { 'task_state' => task.info.state, 'was_cancelled' => task.info.cancelled } end
# File lib/fog/vsphere/requests/compute/vm_suspend.rb, line 5 def vm_suspend(options = {}) raise(ArgumentError, 'instance_uuid is a required parameter') unless options.key?('instance_uuid') options = { 'force' => false }.merge(options) search_filter = { :uuid => options['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm = connection.searchIndex.FindAllByUuid(search_filter).first if options['force'] suspend_forcefully(vm) else suspend_gracefully(vm) end end
# File lib/fog/vsphere/requests/compute/vm_take_snapshot.rb, line 5 def vm_take_snapshot(options = {}) raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid' raise ArgumentError, "name is a required parameter" unless options.key? 'name' vm = get_vm_ref(options['instance_uuid']) task = vm.CreateSnapshot_Task( :name => options['name'], :description => options['description'] || '', :memory => options['memory'] || true, :quiesce => options['quiesce'] || false ) task.wait_for_completion { 'task_state' => task.info.state, 'was_cancelled' => task.info.cancelled } end
Protected Instance Methods
# File lib/fog/vsphere/requests/compute/list_folders.rb, line 38 def child_folders folder [folder, folder.childEntity.grep(RbVmomi::VIM::Folder).map(&method(:child_folders)).flatten] end
# File lib/fog/vsphere/requests/compute/list_child_snapshots.rb, line 22 def child_snapshot_info(snap_tree, parent_snap) { :name => snap_tree.name, :quiesced => snap_tree.quiesced, :description => snap_tree.description, :create_time => snap_tree.createTime, :power_state => snap_tree.state, :ref => snap_tree.snapshot._ref, :mo_ref => snap_tree.snapshot, :tree_node => snap_tree, :snapshot_name_chain => "#{parent_snap.snapshot_name_chain}/#{snap_tree.name}", :ref_chain => "#{parent_snap.ref_chain}/#{snap_tree.snapshot._ref}", :server_id => parent_snap.server_id } end
# File lib/fog/vsphere/requests/compute/list_clusters.rb, line 36 def cluster_attributes(cluster, datacenter_name) { :id => managed_obj_id(cluster), :name => cluster.name, :full_path => cluster_path(cluster, datacenter_name), :num_host => cluster.summary.numHosts, :num_cpu_cores => cluster.summary.numCpuCores, :overall_status => cluster.summary.overallStatus, :datacenter => datacenter_name || parent_attribute(cluster.path, :datacenter)[1] } end
# File lib/fog/vsphere/requests/compute/list_clusters.rb, line 48 def cluster_path(cluster, datacenter_name) datacenter = find_raw_datacenter(datacenter_name) cluster.pretty_path.gsub(%r{(^#{Regexp.escape(datacenter_name)}|#{Regexp.escape(datacenter.hostFolder.name)})\/}, '') end
# File lib/fog/vsphere/requests/compute/list_compute_resources.rb, line 26 def compute_resource_attributes compute_resource, datacenter overall_usage = compute_resource.host.inject({:overallCpuUsage=>0, :overallMemoryUsage=>0}) do |sum, host| { :overallCpuUsage => sum[:overallCpuUsage]+(host.summary.quickStats.overallCpuUsage || 0), :overallMemoryUsage=> sum[:overallMemoryUsage]+(host.summary.quickStats.overallMemoryUsage || 0) } end { :id => managed_obj_id(compute_resource), :name => compute_resource.name, :totalCpu => compute_resource.summary.totalCpu, :totalMemory => compute_resource.summary.totalMemory, :numCpuCores => compute_resource.summary.numCpuCores, :numCpuThreads => compute_resource.summary.numCpuThreads, :effectiveCpu => compute_resource.summary.effectiveCpu, :effectiveMemory => compute_resource.summary.effectiveMemory, :numHosts => compute_resource.summary.numHosts, :numEffectiveHosts => compute_resource.summary.numEffectiveHosts, :overallStatus => compute_resource.summary.overallStatus, :overallCpuUsage => overall_usage[:overallCpuUsage], :overallMemoryUsage => overall_usage[:overallMemoryUsage], :effective => compute_resource.summary.numEffectiveHosts > 0, :isSingleHost => compute_resource.summary.numHosts == 1 } end
# File lib/fog/vsphere/requests/compute/list_hosts.rb, line 35 def compute_resource_host_traversal_spec RbVmomi::VIM.TraversalSpec( :name => 'computeResourceHostTraversalSpec', :type => 'ComputeResource', :path => 'host', :skip => false ) end
# File lib/fog/vsphere/requests/compute/list_datastores.rb, line 25 def datastore_attributes datastore, datacenter { :id => managed_obj_id(datastore), :name => datastore.name, :accessible => datastore.summary.accessible, :type => datastore.summary.type, :freespace => datastore.summary.freeSpace, :capacity => datastore.summary.capacity, :uncommitted => datastore.summary.uncommitted, :datacenter => datacenter, } end
# File lib/fog/vsphere/requests/compute/list_datacenters.rb, line 41 def find_datacenters name=nil name ? [find_raw_datacenter(name)] : raw_datacenters end
# File lib/fog/vsphere/requests/compute/get_datacenter.rb, line 13 def find_raw_datacenter name raw_datacenters.find {|d| d.name == name} || get_raw_datacenter(name) end
# File lib/fog/vsphere/requests/compute/get_folder.rb, line 49 def folder_attributes(folder, datacenter_name) { :id => managed_obj_id(folder), :name => folder.name, :parent => folder.parent.name, :datacenter => datacenter_name, :type => folder_type(folder), :path => folder_path(folder), } end
# File lib/fog/vsphere/requests/compute/get_folder.rb, line 60 def folder_path(folder) "/"+folder.path.map(&:last).join('/') end
# File lib/fog/vsphere/requests/compute/get_folder.rb, line 64 def folder_type(folder) types = folder.childType return :vm if types.include?('VirtualMachine') return :network if types.include?('Network') return :datastore if types.include?('Datastore') end
# File lib/fog/vsphere/requests/compute/get_cluster.rb, line 13 def get_raw_cluster(name, datacenter_name) dc = find_raw_datacenter(datacenter_name) dc.find_compute_resource(name) end
# File lib/fog/vsphere/requests/compute/list_clusters.rb, line 26 def get_raw_clusters_from_folder(folder) folder.childEntity.map do |child_entity| if child_entity.is_a? RbVmomi::VIM::ComputeResource child_entity elsif child_entity.is_a? RbVmomi::VIM::Folder get_raw_clusters_from_folder(child_entity) end end.flatten end
# File lib/fog/vsphere/requests/compute/get_compute_resource.rb, line 13 def get_raw_compute_resource(name, datacenter_name) find_raw_datacenter(datacenter_name).find_compute_resource(name) end
# File lib/fog/vsphere/requests/compute/get_datacenter.rb, line 17 def get_raw_datacenter name connection.serviceInstance.find_datacenter(name) end
# File lib/fog/vsphere/requests/compute/list_datacenters.rb, line 31 def get_raw_datacenters_from_folder folder=nil folder.childEntity.map do | childE | if childE.is_a? RbVmomi::VIM::Datacenter childE elsif childE.is_a? RbVmomi::VIM::Folder get_raw_datacenters_from_folder childE end end.flatten end
# File lib/fog/vsphere/requests/compute/get_datastore.rb, line 13 def get_raw_datastore(name, datacenter_name) get_raw_datastores(datacenter_name).detect { |ds| ds.name == name } end
# File lib/fog/vsphere/requests/compute/get_datastore.rb, line 17 def get_raw_datastores(datacenter_name) list_container_view(datacenter_name, 'Datastore', :datastoreFolder) end
# File lib/fog/vsphere/requests/compute/get_host.rb, line 12 def get_raw_host(name, cluster_name, datacenter_name) cluster = get_raw_cluster(cluster_name, datacenter_name) cluster.host.find { |host| host.name == name } or raise Fog::Compute::Vsphere::NotFound, "no such host #{name}" end
# File lib/fog/vsphere/requests/compute/get_network.rb, line 13 def get_raw_network(name, datacenter_name, distributedswitch=nil) finder = choose_finder(name, distributedswitch) get_all_raw_networks(datacenter_name).find { |n| finder.call(n) } end
# File lib/fog/vsphere/requests/compute/get_resource_pool.rb, line 13 def get_raw_resource_pool(name, cluster_name, datacenter_name) dc = find_raw_datacenter(datacenter_name) cluster = dc.find_compute_resource(cluster_name) name.nil? ? cluster.resourcePool : cluster.resourcePool.traverse(name) end
# File lib/fog/vsphere/requests/compute/get_server_type.rb, line 13 def get_raw_server_type(id, datacenter, filter={}) types=raw_server_types(datacenter) raise(Fog::Compute::Vsphere::NotFound) unless types types=types.select{ | servertype | servertype.id == id }.first raise(Fog::Compute::Vsphere::NotFound) unless types types end
# File lib/fog/vsphere/requests/compute/get_storage_pod.rb, line 13 def get_raw_storage_pod(name, datacenter_name) raw_storage_pods(datacenter_name).detect { |pod| pod.name == name} end
# File lib/fog/vsphere/requests/compute/get_folder.rb, line 26 def get_raw_vmfolder(path, datacenter_name) # The required path syntax - 'topfolder/subfolder # Clean up path to be relative since we're providing datacenter name dc = find_raw_datacenter(datacenter_name) dc_root_folder = dc.vmFolder # Filter the root path for this datacenter not to be used." dc_root_folder_path=dc_root_folder.path.map { | id, name | name }.join("/") paths = path.sub(/^\/?#{Regexp.quote(dc_root_folder_path)}\/?/, '').split('/') return dc_root_folder if paths.empty? # Walk the tree resetting the folder pointer as we go paths.reduce(dc_root_folder) do |last_returned_folder, sub_folder| # JJM VIM::Folder#find appears to be quite efficient as it uses the # searchIndex It certainly appears to be faster than # VIM::Folder#inventory since that returns _all_ managed objects of # a certain type _and_ their properties. sub = last_returned_folder.find(sub_folder, RbVmomi::VIM::Folder) raise Fog::Compute::Vsphere::NotFound, "Could not descend into #{sub_folder}. Please check your path. #{path}" unless sub sub end end
# File lib/fog/vsphere/requests/compute/list_folders.rb, line 33 def get_raw_vmfolders(path, datacenter_name) folder = get_raw_vmfolder(path, datacenter_name) child_folders(folder).flatten.compact end
# File lib/fog/vsphere/requests/compute/get_virtual_machine.rb, line 31 def get_vm_by_name(name, dc, folder, recursive) if folder # This returns an Enumerator, which when called with .find will # search only until it finds the VM we're looking for vms = raw_list_all_virtual_machines_in_folder(folder, dc, recursive) else vms = raw_list_all_virtual_machines(dc) end if name.include?('/') folder = File.dirname(name) basename = File.basename(name) vms.find do |v| begin v["name"] == basename && v.parent.pretty_path.include?(folder) rescue RbVmomi::VIM::ManagedObjectNotFound false end end else vms.find do |v| begin v["name"] == name rescue RbVmomi::VIM::ManagedObjectNotFound false end end end end
# File lib/fog/vsphere/requests/compute/get_virtual_machine.rb, line 12 def get_vm_ref(id, dc = nil, folder = nil, recursive = false) raw_datacenter = find_raw_datacenter(dc) if dc vm = case is_uuid?(id) # UUID based when true params = {:uuid => id, :vmSearch => true, :instanceUuid => true} params[:datacenter] = raw_datacenter if dc connection.searchIndex.FindByUuid(params) else # try to find based on VM name if dc get_vm_by_name(id, dc, folder, recursive) else raw_datacenters.map { |d| get_vm_by_name(id, d["name"], folder, recursive)}.compact.first end end vm ? vm : raise(Fog::Compute::Vsphere::NotFound, "#{id} was not found") end
# File lib/fog/vsphere/requests/compute/list_groups.rb, line 12 def group_attributes(group, filters) attributes = {} attributes[:datacenter] = filters[:datacenter] attributes[:cluster] = filters[:cluster] attributes[:name] = group[:name] attributes[:type] = group.class if group.class.to_s == 'ClusterVmGroup' then attributes[:vm_ids] = group[:vm].map {|vm| vm.config.instanceUuid} end if group.class.to_s == 'ClusterHostGroup' then attributes[:hosts] = group[:host].map {|host| host.name} end return attributes end
# File lib/fog/vsphere/requests/compute/list_hosts.rb, line 58 def host_system_attribute_mapping { name: 'name', cpu_cores: 'hardware.cpuInfo.numCpuCores', cpu_sockets: 'hardware.cpuInfo.numCpuPackages', cpu_threads: 'hardware.cpuInfo.numCpuThreads', memory: 'hardware.memorySize', uuid: 'hardware.systemInfo.uuid', model: 'hardware.systemInfo.model', vendor: 'hardware.systemInfo.vendor', product_name: 'summary.config.product.name', product_version: 'summary.config.product.version', hostname: 'config.network.dnsConfig.hostName', domainname: 'config.network.dnsConfig.domainName' } end
# File lib/fog/vsphere/requests/compute/list_hosts.rb, line 44 def host_system_filter_spec(obj) RbVmomi::VIM.PropertyFilterSpec( :objectSet => [ :obj => obj, :selectSet => [ compute_resource_host_traversal_spec ] ], :propSet => [ { :type => 'HostSystem', :pathSet => host_system_attribute_mapping.values + ['config.network.vnic', 'vm'] } ] ) end
root ResourcePool + Children if they exists
# File lib/fog/vsphere/requests/compute/list_resource_pools.rb, line 17 def list_raw_resource_pools(cluster) pools = [] traverse_raw_resource_pools(pools, cluster.resourcePool) pools.uniq end
# File lib/fog/vsphere/requests/compute/list_hosts.rb, line 24 def map_attrs_to_hash(obj, attribute_mapping) attribute_mapping.each_with_object({}) do |(k, v), hsh| hsh[k] = obj[v] end end
# File lib/fog/vsphere/requests/compute/list_networks.rb, line 26 def network_attributes(network, datacenter) if network.kind_of?(RbVmomi::VIM::DistributedVirtualPortgroup) id = network.key virtualswitch = network.config.distributedVirtualSwitch.name vlanid = raw_network_vlan(network.config.defaultPortConfig) else id = managed_obj_id(network) virtualswitch = nil vlanid = nil end { :id => id, :name => network.name, :accessible => network.summary.accessible, :datacenter => datacenter, :virtualswitch => virtualswitch, :vlanid => vlanid } end
# File lib/fog/vsphere/requests/compute/list_hosts.rb, line 30 def property_collector_results(filter_spec) property_collector = connection.serviceContent.propertyCollector property_collector.RetrieveProperties(:specSet => [filter_spec]) end
# File lib/fog/vsphere/requests/compute/list_datacenters.rb, line 26 def raw_datacenters folder=nil folder ||= connection.rootFolder @raw_datacenters ||= get_raw_datacenters_from_folder folder end
# File lib/fog/vsphere/requests/compute/list_datacenters.rb, line 18 def raw_getpathmo mo if mo.parent == nil or mo.parent.name == connection.rootFolder.name then [ mo.name ] else [ raw_getpathmo(mo.parent), mo.name ].flatten end end
# File lib/fog/vsphere/requests/compute/list_resource_pools.rb, line 38 def resource_pool_attributes(resource_pool, cluster, datacenter) name = folder_path(resource_pool).gsub(/^.*Resources(\/|)/,'') name = 'Resources' if name.empty? { :id => managed_obj_id(resource_pool), :name => name, :configured_memory_mb => resource_pool.summary.configuredMemoryMB, :overall_status => resource_pool.overallStatus, :cluster => cluster, :datacenter => datacenter } end
# File lib/fog/vsphere/requests/compute/list_rules.rb, line 12 def rule_attributes(rule, filters) attributes = {} attributes[:datacenter] = filters[:datacenter] attributes[:cluster] = filters[:cluster] attributes[:key] = rule[:key] attributes[:name] = rule[:name] attributes[:enabled] = rule[:enabled] attributes[:type] = rule.class if rule.class.to_s == 'ClusterAntiAffinityRuleSpec' || rule.class.to_s == 'ClusterAffinityRuleSpec' attributes[:vm_ids] = rule[:vm].map {|vm| vm.config.instanceUuid} elsif rule.class.to_s == 'ClusterVmHostRuleInfo' attributes[:mandatory] = rule[:mandatory] attributes[:vmGroupName] = rule[:vmGroupName] attributes[:affineHostGroupName] = rule[:affineHostGroupName] end return attributes end
# File lib/fog/vsphere/requests/compute/list_server_types.rb, line 28 def server_type_attributes(servertype, datacenter) { :id => servertype.id, :name => servertype.id, :family => servertype.family, :fullname => servertype.fullName, :datacenter => datacenter, } end
# File lib/fog/vsphere/requests/compute/list_vm_snapshots.rb, line 23 def snapshot_info(snap_tree, vm_id) { :name => snap_tree.name, :quiesced => snap_tree.quiesced, :description => snap_tree.description, :create_time => snap_tree.createTime, :power_state => snap_tree.state, :ref => snap_tree.snapshot._ref, :mo_ref => snap_tree.snapshot, :tree_node => snap_tree, :ref_chain => "#{vm_id}/#{snap_tree.snapshot._ref}", :snapshot_name_chain => "#{vm_id}/#{snap_tree.name}", :server_id => vm_id } end
# File lib/fog/vsphere/requests/compute/list_storage_pods.rb, line 20 def storage_pod_attributes(storage_pod, datacenter) { :id => managed_obj_id(storage_pod), :name => storage_pod.name, :freespace => storage_pod.summary.freeSpace, :capacity => storage_pod.summary.capacity, :datacenter => datacenter, } end
# File lib/fog/vsphere/requests/compute/list_resource_pools.rb, line 23 def traverse_raw_resource_pools(pools, rp) if rp if rp.respond_to? :resourcePool traverse_raw_resource_pools(pools, rp.resourcePool) end if rp.respond_to? :each rp.each do |resourcePool| traverse_raw_resource_pools(pools, resourcePool) end else pools << rp end end end
Private Instance Methods
# File lib/fog/vsphere/requests/compute/modify_vm_interface.rb, line 55 def apply_options_to_raw_interface(raw_interface, options) if options[:connectable] options[:connectable].each do |key, value| raw_interface.connectable.send("#{key}=", value) end end raw_interface end
# File lib/fog/vsphere/compute.rb, line 645 def authenticate begin @connection.serviceContent.sessionManager.Login :userName => @vsphere_username, :password => @vsphere_password rescue RbVmomi::VIM::InvalidLogin => e raise Fog::Vsphere::Errors::ServiceError, e.message end end
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 114 def boot_options(attributes, vm_cfg) # NOTE: you must be using vsphere_rev 5.0 or greater to set boot_order # e.g. Fog::Compute.new(provider: "vsphere", vsphere_rev: "5.5", etc) options = {} if @vsphere_rev.to_f >= 5 and attributes[:boot_order] options[:bootOrder] = boot_order(attributes, vm_cfg) end # Set attributes[:boot_retry] to a delay in miliseconds to enable boot retries if attributes[:boot_retry] options[:bootRetryEnabled] = true options[:bootRetryDelay] = attributes[:boot_retry] end options.empty? ? nil : RbVmomi::VIM::VirtualMachineBootOptions.new(options) end
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 131 def boot_order(attributes, vm_cfg) # attributes[:boot_order] may be an array like this ['network', 'disk'] # stating, that we want to prefer network boots over disk boots boot_order = [] attributes[:boot_order].each do |boot_device| case boot_device when 'network' if nics = attributes[:interfaces] # key is based on 4000 + the interface index # we allow booting from all network interfaces, the first interface has the highest priority nics.each do |nic| boot_order << RbVmomi::VIM::VirtualMachineBootOptionsBootableEthernetDevice.new( :deviceKey => 4000 + nics.index(nic), ) end end when 'disk' disks = vm_cfg[:deviceChange].map {|dev| dev[:device]}.select { |dev| dev.is_a? RbVmomi::VIM::VirtualDisk } disks.each do |disk| # we allow booting from all harddisks, the first disk has the highest priority boot_order << RbVmomi::VIM::VirtualMachineBootOptionsBootableDiskDevice.new( :deviceKey => disk.key ) end when 'cdrom' boot_order << RbVmomi::VIM::VirtualMachineBootOptionsBootableCdromDevice.new when 'floppy' boot_order << RbVmomi::VIM::VirtualMachineBootOptionsBootableFloppyDevice.new else raise "failed to create boot device because \"#{boot_device}\" is unknown" end end boot_order end
# File lib/fog/vsphere/compute.rb, line 597 def connect # This is a state variable to allow digest validation of the SSL cert bad_cert = false loop do begin @connection = RbVmomi::VIM.new :host => @vsphere_server, :port => @vsphere_port, :path => @vsphere_path, :ns => @vsphere_ns, :rev => @vsphere_rev, :ssl => @vsphere_ssl, :insecure => bad_cert, :debug => @vsphere_debug # Create a shadow class to change the behaviour of @connection.obj2xml # so that xsd:any types are converted to xsd:int (and not xsd:long). # # This is a known issue with RbVmomi. # # See https://communities.vmware.com/message/2505334 for discussion # and https://github.com/rlane/rbvmomi/pull/30 for an unmerged # pull request that fixes it in RbVmomi. # class <<@connection def obj2xml xml, name, type, is_array, o, attrs={} case o when Integer attrs['xsi:type'] = 'xsd:int' if type(type) == RbVmomi::BasicTypes::AnyType xml.tag! name, o.to_s, attrs xml else super xml, name, type, is_array, o, attrs end end end break rescue OpenSSL::SSL::SSLError raise if bad_cert bad_cert = true end end if bad_cert then validate_ssl_connection end end
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 217 def controller_default_options {:operation => :add, :type => RbVmomi::VIM.VirtualLsiLogicController.class, :shared => false } end
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 268 def create_cdrom cdrom, index = 0, operation = :add, controller_key = 200 { :operation => operation, :device => RbVmomi::VIM.VirtualCdrom( :key => cdrom.key || index, :backing => RbVmomi::VIM::VirtualCdromRemoteAtapiBackingInfo(deviceName: ''), :controllerKey => controller_key, connectable: RbVmomi::VIM::VirtualDeviceConnectInfo( startConnected: false, connected: false, allowGuestControl: true, ), ) } end
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 196 def create_controller(controller=nil, index = 0) options=if controller controller_default_options.merge(controller.attributes) else controller_default_options end controller_class=if options[:type].is_a? String then Fog::Vsphere.class_from_string options[:type], "RbVmomi::VIM" else options[:type] end { :operation => options[:operation], :device => controller_class.new({ :key => options[:key] || (1000 + index), :busNumber => options[:bus_id] || index, :sharedBus => controller_get_shared_from_options(options), }) } end
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 233 def create_disk(disk, operation = :add, options = {}) # If we deploy the vm on a storage pod, datastore has to be an empty string if options[:storage_pod] datastore = '' else datastore = "[#{disk.datastore}]" end disk.set_unit_number disk.set_key payload = { :operation => operation, :device => RbVmomi::VIM.VirtualDisk( :key => disk.key, :backing => RbVmomi::VIM.VirtualDiskFlatVer2BackingInfo( :fileName => options[:filename] || datastore, :diskMode => disk.mode.to_sym, :thinProvisioned => disk.thin ), :controllerKey => disk.controller_key, :unitNumber => disk.unit_number, :capacityInKB => disk.size ) } file_operation = options[:file_operation] || (:create if operation == :add) payload[:fileOperation] = file_operation if file_operation if operation == :add && disk.thin == 'false' && disk.eager_zero == 'true' payload[:device][:backing][:eagerlyScrub] = disk.eager_zero end payload end
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 181 def create_interface nic, index = 0, operation = :add, attributes = {} { :operation => operation, :device => nic.type.new( :key => index, :deviceInfo => { :label => nic.name, :summary => nic.summary, }, :backing => create_nic_backing(nic, attributes), :addressType => 'generated') } end
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 166 def create_nic_backing nic, attributes raw_network = get_raw_network(nic.network, attributes[:datacenter], if nic.virtualswitch then nic.virtualswitch end) if raw_network.kind_of? RbVmomi::VIM::DistributedVirtualPortgroup RbVmomi::VIM.VirtualEthernetCardDistributedVirtualPortBackingInfo( :port => RbVmomi::VIM.DistributedVirtualSwitchPortConnection( :portgroupKey => raw_network.key, :switchUuid => raw_network.config.distributedVirtualSwitch.uuid ) ) else RbVmomi::VIM.VirtualEthernetCardNetworkBackingInfo(:deviceName => nic.network) end end
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 47 def create_vm_on_datastore(vm_cfg, vmFolder, resource_pool, host = nil) vm = vmFolder.CreateVM_Task(:config => vm_cfg, :pool => resource_pool, :host => host).wait_for_completion end
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 51 def create_vm_on_storage_pod(storage_pod, vm_cfg, vmFolder, resource_pool, datacenter, host = nil) pod_spec = RbVmomi::VIM::StorageDrsPodSelectionSpec.new( :storagePod => get_raw_storage_pod(storage_pod, datacenter), ) storage_spec = RbVmomi::VIM::StoragePlacementSpec.new( :type => 'create', :folder => vmFolder, :resourcePool => resource_pool, :podSelectionSpec => pod_spec, :configSpec => vm_cfg, :host => host, ) srm = connection.serviceContent.storageResourceManager result = srm.RecommendDatastores(:storageSpec => storage_spec) # if result array contains recommendation, we can apply it if key = result.recommendations.first.key result = srm.ApplyStorageDrsRecommendation_Task(:key => [key]).wait_for_completion vm = result.vm else raise "Could not create vm on storage pod, did not get a storage recommendation" end vm end
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 94 def device_change attributes devices = [] if (nics = attributes[:interfaces]) devices << nics.map { |nic| create_interface(nic, nics.index(nic), :add, attributes) } end if (scsi_controllers = (attributes[:scsi_controllers] || attributes["scsi_controller"])) devices << scsi_controllers.each_with_index.map { |controller, index| create_controller(controller, index) } end if (disks = attributes[:volumes]) devices << disks.map { |disk| create_disk(disk, :add, storage_pod: get_storage_pod(attributes)) } end if (cdroms = attributes[:cdroms]) devices << cdroms.map { |cdrom| create_cdrom(cdrom, cdroms.index(cdrom)) } end devices.flatten end
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 284 def extra_config attributes extra_config = attributes[:extra_config] || {'bios.bootOrder' => 'ethernet0'} extra_config.map {|k,v| {:key => k, :value => v.to_s} } end
An enumerator for a folder. Enumerates all the VMs in the folder, recursively if passed recursive=true
# File lib/fog/vsphere/requests/compute/list_virtual_machines.rb, line 37 def folder_enumerator(raw_folder, recursive) Enumerator.new do |yielder| raw_folder.children.each do |child| case child when RbVmomi::VIM::Folder folder_enumerator(child, true).each {|item| yielder.yield item} if recursive when RbVmomi::VIM::VirtualMachine yielder.yield child end end end end
# File lib/fog/vsphere/requests/compute/list_virtual_machines.rb, line 68 def get_folder_path(folder, root = nil) return if (!folder.methods.include?('parent')) || (folder == root) "#{get_folder_path(folder.parent)}/#{folder.name}" end
# File lib/fog/vsphere/requests/compute/create_group.rb, line 29 def get_group_spec(attributes={}) if attributes[:type].to_s == 'ClusterVmGroup' vms = attributes[:vm_ids].to_a.map {|id| get_vm_ref(id, attributes[:datacenter])} attributes[:type].new( name: attributes[:name], vm: vms ) elsif attributes[:type].to_s == 'ClusterHostGroup' attributes[:type].new( name: attributes[:name], host: attributes[:host_refs] ) end end
# File lib/fog/vsphere/requests/compute/modify_vm_interface.rb, line 39 def get_interface_from_options(vmid, options) if options and options[:interface] options[:interface] elsif options[:key] and options[:key]>0 oldattributes = get_vm_interface(vmid, options) Fog::Compute::Vsphere::Interface.new(oldattributes.merge(options)) elsif options[:type] and options[:network] Fog::Compute::Vsphere::Interface.new options else raise ArgumentError, "interface is a required parameter or pass options with type and network" end end
# File lib/fog/vsphere/requests/compute/create_rule.rb, line 30 def get_rule_spec(attributes={}) if (attributes[:type].to_s == 'ClusterAntiAffinityRuleSpec' || attributes[:type].to_s == 'ClusterAffinityRuleSpec') vms = attributes[:vm_ids].to_a.map {|id| get_vm_ref(id, attributes[:datacenter])} attributes[:type].new( name: attributes[:name], enabled: attributes[:enabled], vm: vms ) elsif attributes[:type].to_s == 'ClusterVmHostRuleInfo' attributes[:type].new( name: attributes[:name], enabled: attributes[:enabled], mandatory: attributes[:mandatory], vmGroupName: attributes[:vmGroupName], affineHostGroupName: attributes[:affineHostGroupName] ) end end
check if a storage pool is set on any of the volumes and return the first result found or nil return early if vsphere revision is lower than 5 as this is not supported
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 78 def get_storage_pod attributes return unless @vsphere_rev.to_f >= 5 volume = attributes[:volumes].detect {|volume| !( volume.storage_pod.nil? || volume.storage_pod.empty? ) } volume.storage_pod if volume end
# File lib/fog/vsphere/requests/compute/list_templates.rb, line 26 def list_all_templates(options = {}) datacenters = find_datacenters(options[:datacenter]) vms = datacenters.map do |dc| list_container_view(dc, 'VirtualMachine', :vmFolder) end.flatten # remove all virtual machines that are not templates vms.delete_if { |v| v.config.nil? || !v.config.template } vms.map(&method(:convert_vm_mob_ref_to_attr_hash)) end
# File lib/fog/vsphere/requests/compute/list_templates.rb, line 16 def list_all_templates_in_folder(path, datacenter_name) folder = get_raw_vmfolder(path, datacenter_name) vms = folder.children.grep(RbVmomi::VIM::VirtualMachine) # remove all virtual machines that are not template vms.delete_if { |v| v.config.nil? or not v.config.template } vms.map(&method(:convert_vm_mob_ref_to_attr_hash)) end
# File lib/fog/vsphere/requests/compute/list_virtual_machines.rb, line 50 def list_all_virtual_machines(options = { }) raw_vms = raw_list_all_virtual_machines(options[:datacenter]) vms = convert_vm_view_to_attr_hash(raw_vms) # remove all template based virtual machines vms.delete_if { |v| v['template'] } vms end
# File lib/fog/vsphere/requests/compute/list_virtual_machines.rb, line 23 def list_all_virtual_machines_in_folder(path, datacenter_name, recursive) vms = raw_list_all_virtual_machines_in_folder(path, datacenter_name, recursive).to_a # remove all template based virtual machines vms.delete_if { |v| v.config.nil? || v.config.template } vms.map(&method(:convert_vm_mob_ref_to_attr_hash)) end
# File lib/fog/vsphere/compute.rb, line 664 def list_container_view(datacenter_obj_or_name, type, container_object = nil) dc = if datacenter_obj_or_name.kind_of?(String) find_raw_datacenter(datacenter_obj_or_name) else datacenter_obj_or_name end container = if container_object dc.public_send(container_object) else dc end container_view = connection.serviceContent.viewManager.CreateContainerView( :container => dc, :type => [type], :recursive => true ) result = container_view.view container_view.DestroyView result end
# File lib/fog/vsphere/compute.rb, line 586 def negotiate_revision(revision = nil) # Negotiate the API revision if not revision rev = @connection.serviceContent.about.apiVersion @connection.rev = [ rev, ENV['FOG_VSPHERE_REV'] || '4.1' ].max end @vsphere_is_vcenter = @connection.serviceContent.about.apiType == "VirtualCenter" @vsphere_rev = @connection.rev end
# File lib/fog/vsphere/requests/compute/list_virtual_machines.rb, line 59 def raw_list_all_virtual_machines(datacenter_name = nil) ## Moved this to its own function since trying to get a list of all virtual machines ## to parse for a find function took way too long. The raw list returned will make it ## much faster to interact for some functions. datacenters = find_datacenters(datacenter_name) datacenters.map do |dc| list_container_view(dc, 'VirtualMachine', :vmFolder) end.flatten end
# File lib/fog/vsphere/requests/compute/list_virtual_machines.rb, line 30 def raw_list_all_virtual_machines_in_folder(path, datacenter_name, recursive) folder = get_raw_vmfolder(path, datacenter_name) folder_enumerator(folder, recursive) end
# File lib/fog/vsphere/requests/compute/list_networks.rb, line 48 def raw_network_vlan(network) case network when RbVmomi::VIM::VMwareDVSPortSetting raw_network_vlan_id(network.vlan) else nil end end
# File lib/fog/vsphere/requests/compute/list_networks.rb, line 57 def raw_network_vlan_id(vlan) case vlan when RbVmomi::VIM::VmwareDistributedVirtualSwitchVlanIdSpec vlan.vlanId else nil end end
# File lib/fog/vsphere/requests/compute/list_storage_pods.rb, line 14 def raw_storage_pods(datacenter_name) list_container_view(datacenter_name, 'StoragePod') end
# File lib/fog/vsphere/requests/compute/list_vm_interfaces.rb, line 64 def raw_to_hash(nic) { :name => nic.deviceInfo.label, :mac => nic.macAddress, :network => nic.backing.respond_to?("network") ? nic.backing.network.name : nic.backing.port.portgroupKey, :status => nic.connectable.status, :connected => nic.connectable.connected, :summary => nic.deviceInfo.summary, :type => nic.class, :key => nic.key, } end
# File lib/fog/vsphere/requests/compute/vm_suspend.rb, line 21 def suspend_forcefully(vm) task = vm.SuspendVM_Task task.wait_for_completion { 'task_state' => task.info.result, 'suspend_type' => 'suspend' } end
# File lib/fog/vsphere/requests/compute/vm_suspend.rb, line 30 def suspend_gracefully(vm) vm.StandbyGuest { 'task_state' => 'running', 'suspend_type' => 'standby_guest' } end
Verify a SSL certificate based on the hashed public key
# File lib/fog/vsphere/compute.rb, line 655 def validate_ssl_connection pubkey = @connection.http.peer_cert.public_key pubkey_hash = Digest::SHA2.hexdigest(pubkey.to_s) expected_pubkey_hash = @vsphere_expected_pubkey_hash if pubkey_hash != expected_pubkey_hash then raise Fog::Vsphere::Errors::SecurityError, "The remote system presented a public key with hash #{pubkey_hash} but we're expecting a hash of #{expected_pubkey_hash || '<unset>'}. If you are sure the remote system is authentic set vsphere_expected_pubkey_hash: <the hash printed in this message> in ~/.fog" end end
this methods defines where the vm config files would be located, by default we prefer to keep it at the same place the (first) vmdk is located if we deploy the vm on a storage pool, we have to return an empty string
# File lib/fog/vsphere/requests/compute/create_vm.rb, line 87 def vm_path_name attributes return '' if get_storage_pod(attributes) datastore = attributes[:volumes].first.datastore unless attributes[:volumes].empty? datastore ||= 'datastore1' "[#{datastore}]" end