Category Archives: vCenter and ESXi

General vCenter and ESXi related posts

Getting started with vCenter server REST APIs using python

You already might have noticed, as part of vSphere 6.5, VMware introduced vCenter Server REST APIs. I really enjoyed playing around them using vCenter apiexplorer as well as Postman REST client. Recently, I wanted to code around these APIs using one of the programming languages and I am happy that I was able to do it using Python. I thought it is worth to share with you. In this blog post, I will take you through all the steps required to get started with vCenter REST API using python. Here we go.

Step 1. First important thing is to get familiar with vCenter server REST API documentation. Similar documentation is available from vCenter apiexplorer as well. I would recommend you to play with apiexplorer, which will not only make you familiar with documentation but also will enable you to quickly invoke these APIs against your vCenter server. I am sure you will be pretty impressed on REST API documentation when compared to older vSphere SOAP API documentation.

Step 2. Once you explore the first step , we can get started with environment creation for REST APIs using python. If you ask me, it is fairly easy and quick, we just need to have python installed machine, where we need to install “requests” python module as follows

$ pip install requests

Step 3. Now let us take a look at below python module developed to simplify REST API usage.

# Author: Vikas Shitole
# Website: www.vThinkBeyondVM.com
# Product: vCenter server
# Description: Python module for vCenter server REST APIs
# Reference:https://code.vmware.com/apis/191/vsphere-automation
# How to setup vCenter REST API environment?: Just have VM with python and install "requests" python library using pip

import requests
import json
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

s=requests.Session()
s.verify=False

# Function to get the vCenter server session
def get_vc_session(vcip,username,password):
         s.post('https://'+vcip+'/rest/com/vmware/cis/session',auth=(username,password))
         return s

# Function to get all the VMs from vCenter inventory
def get_vms(vcip):
        vms=s.get('https://'+vcip+'/rest/vcenter/vm')
        return vms

#Function to power on particular VM
def poweron_vm(vmmoid,vcip):
        s.post('https://'+vcip+'/rest/vcenter/vm/'+vmmoid+'/power/start')

# Function to power off particular VM
def poweroff_vm(vmmoid,vcip):
        s.post('https://'+vcip+'/rest/vcenter/vm/'+vmmoid+'/power/stop')

Above vcrest.py module is available on my github repo.

Let us understand above code.

Line 8: Imported powerful “requests” python library required to make API calls
Line 9: Imported “json” library required to parse json response we get from REST APIs
Line 10/11: Here we are disabling warnings related to SSL connection. In production, we should not disable it.
Line 13/14: Here we are creating Session object to have session persisted during the current request. If you see “s.verify” is set to False, it does mean that we are ignoring verifying SSL certificates. If you want to set it to true, please take a look at SSL Cert Verification section
Line 16 to 32: I have added 4 methods i.e. get_vc_session(), get_vms(), poweron_vm() & poweroff_vm(). We would be calling these methods from below sample script. If you see, in all the methods, I have used REST API documentation and called these APIs using “requests” library.

Step 4. Now that we understood above “vcrest.py” module, let us import above module into our script to demonstrate its usage.

# Description: Python sample to get VMs and its moid using vCenter server REST API.
# Reference:https://code.vmware.com/apis/191/vsphere-automation
#  Make sure you have "rest.py" file into your python directory.

import vcrest
import json
vcip="10.192.23.143" # vCenter server ip address/FQDN

#Get vCenter server session and can be used as needed. pass vcenter username & password
vcsession = vcrest.get_vc_session(vcip,"Administrator@vsphere.local","VMware1!")

#Get all the VMs from inventory using below method from "vcrest" module.
vms = vcrest.get_vms(vcip)

# Parsing the JSON response we got from above function call (it has all the Vms present in inventory
vm_response=json.loads(vms.text)
json_data=vm_response["value"]

print "VM names and its unique MOID"
print "============================"
for vm in json_data:
        print vm.get("name")+" :: "+vm.get("vm")
        #We are powering on all the VMs those are in powered off state
        if vm.get("power_state") == "POWERED_OFF":
                vcrest.poweron_vm(vm.get("vm"),vcip)

Above script i.e. vcrestsample.py is available on my github repo as well

Output :
vmware@localhost:~$ python vcrestsample.py
VM names and its unique MOID
============================
NTP-India-1 :: vm-42
NTP-PA-2 :: vm-43
WebApp-1 :: vm-44
vThinkBeyondVM :: vm-45
vmware@localhost:~$

Let us understand above script.

Line 5: Imported “vcrest” module we just discussed above.
Line 10: We are getting vCenter server session by calling function defined in “vcrest” module. We can use this session object as needed.
Line 13: We are getting all the VMs from inventory using “get_vms() function defined in “vcrest” module. Note that with this call, we will get JSON response as shown below, which we need to parse to fetch useful information.

{
  "value": [
    {
      "memory_size_MiB": 512,
      "vm": "vm-42",
      "name": "NTP-India-1",
      "power_state": "POWERED_OFF",
      "cpu_count": 1
    },
    {
      "memory_size_MiB": 512,
      "vm": "vm-43",
      "name": "NTP-PA-2",
      "power_state": "POWERED_OFF",
      "cpu_count": 1
    },
    {
      "memory_size_MiB": 512,
      "vm": "vm-44",
      "name": "WebApp-1",
      "power_state": "POWERED_ON",
      "cpu_count": 1
    },
    {
      "memory_size_MiB": 512,
      "vm": "vm-45",
      "name": "vThinkBeyondVM",
      "power_state": "POWERED_ON",
      "cpu_count": 1
    }
  ]
}

Line 16/17: As we got JSON response as pointed above, here we parsed it so that we can easily access as part of python dictionary.
Line 21 to 25: Iterating through dictionary and printing vm names & its moid (managed object id). Finally powering on VMs those are off.

That is all, is not it cool? Since we have REST APIs available for vCenter VM life cycle, VCSA, content library, tagging etc, there is lot to learn and play around. I will keep adding more methods to vcrest.py module. If you are interested in contributing to this module, let me know, it would be really great. In case, you would like to explore vCenter SOAP based APIs, please refer my last post

pyVmomi tutorial : How to get all the core vCenter server inventory objects and play around?

Recently I posted about “how did I get started with pyvmomi?”. I continued exploring this further and I thought to share my learning so far. After setting up the pyvmomi environment, first thing I wanted to learn was to get hold of all core vCenter inventory objects so that I can play around each of them. vCenter core inventory includes objects such as Datacenters, Clusters, Virtual Machines, Hosts, Datastores & Networks etc.
As an initial step, I was looking for a way to get below objects from VC inventory
-All Virtual Machines
-All Clusters
-All Hosts
-All Datacenters

There could be multiple ways to get above objects but below is the way I could achieve this.

from pyVim.connect import SmartConnect
from pyVmomi import vim
import ssl

# Get all the Vms from vCenter server inventory and print its name
# Below is Python 2.7.x code, which can be easily converted to python 3.x version

s=ssl.SSLContext(ssl.PROTOCOL_TLSv1)
s.verify_mode=ssl.CERT_NONE
si= SmartConnect(host="10.192.3.2", user="Administrator@vsphere.local", pwd="$h1vKamal",sslContext=s)
content=si.content

# Method that populates objects of type vimtype
def get_all_objs(content, vimtype):
        obj = {}
        container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
        for managed_object_ref in container.view:
                obj.update({managed_object_ref: managed_object_ref.name})
        return obj

#Calling above method
getAllVms=get_all_objs(content, [vim.VirtualMachine])

#Iterating each vm object and printing its name
for vm in getAllVms:
        print vm.name

Output:
vmware@localhost:~$ python getAllVms.py
Database-server
NTP-Bangalore
Web-server
NTP-Pune
vmware@localhost:~$

You could see above, script listed all the VMs available in inventory. Let us look at another example, here we will get all the clusters from vCenter Inventory.

from pyVim.connect import SmartConnect
from pyVmomi import vim
import ssl

#Get all the Clusters from vCenter invetory and printing its name
#Below is Python 2.7.x code, which can be easily converted to python 3.x version

s=ssl.SSLContext(ssl.PROTOCOL_TLSv1)
s.verify_mode=ssl.CERT_NONE
si= SmartConnect(host="10.192.3.2", user="Administrator@vsphere.local", pwd="$h1vKamal",sslContext=s)
content=c.content

# Method that populates objects of type vimtype
def get_all_objs(content, vimtype):
        obj = {}
        container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
        for managed_object_ref in container.view:
                obj.update({managed_object_ref: managed_object_ref.name})
        return obj

#Calling above method
clusters=get_all_objs(content, [vim.ClusterComputeResource])

#Iterating each cluster object and printing its name
for cluster in clusters:
        print (cluster.name)

Output:
vmware@localhost:~$ python getClusters.py
DRSCluster-USA
DRSCluster-Europe
DRSCluster-India
vmware@localhost:~$

If you notice, only important change from getAllVms and getClusters script is line #22, is not it cool? So now we were able to get all the VMs as well as all the clusters. Similarly we can get other core inventory objects such as datacenter, hosts, datastores, networks etc. Below is how line #22 will look for other vCenter/ESXi objects.

# For ESXi host
hosts=get_all_objs(content, [vim.HostSystem])

#For datacenters
dcs = get_all_objs(content, [vim.Datacenter])

#For datastores 
datastores = get_all_objs(content, [vim.Datastore])

By now we know how to get hold of vSphere inventory objects, let’s do something meaningful with these objects. I chose to call a method on one of clusters that we retrieved above. What is that method?
vCenter 6.0 has introduced one of interesting APIs on vSphere DRS cluster rules. i.e. findRulesForVM(). This method is called on individual cluster and it returns set of DRS VM-VM affinity rules (enabled or disabled) those are associated with given/input VM. Since this method returns VM-VM affinity rules, I first created some VM-VM rules on one of my clusters as follows.

Cluster with DRS enabled
DRS VM-VM rules

Now that DRS rules are created, let us pass VM name as parameter to “findRulesForVM()” API and call this API on that cluster.

Updated code is available on VMware sample exchange portal here

from pyVim.connect import SmartConnect
from pyVmomi import vim
import ssl
#Get DRS VM-VM rules associated with a VM.

s=ssl.SSLContext(ssl.PROTOCOL_TLSv1)
s.verify_mode=ssl.CERT_NONE
si= SmartConnect(host="10.192.3.2", user="Administrator@vsphere.local", pwd="$vabc325pqr",sslContext=s)
content=c.content

def get_all_objs(content, vimtype):
        obj = {}
        container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
        for managed_object_ref in container.view:
                obj.update({managed_object_ref: managed_object_ref.name})
        return obj

# Scanning a input VM inside inventory using special  python construct i.e. List comprehension
# It will get all the Vms and check whether input VM is available inside inventory or not, finally it returns list with matching condition

vmToScan = [vm for vm in get_all_objs(content,[vim.VirtualMachine]) if "NTP-Bangalore" == vm.name]

# Scanning a input cluster inside invetory the way we did for VM above. here also we used list comprehension.

cluster = [cluster for cluster in get_all_objs(content,[vim.ClusterComputeResource]) if "DRSCluster-India" == cluster.name]

# Now we can call the method on input cluster by passing input VM as parameter, it returns array of rule objects associated with input VM.
ClusterRuleInfo=cluster[0].FindRulesForVm(vmToScan[0])

# Now iterate through rule objects and print the rule name

for rule in ClusterRuleInfo:
        print rule.name

Output:
vmware@localhost:~$ python findRules.py
Anti-Affine-NTP-Servers
Affine-Web-DB-Servers

Here is how vSphere web client “recent task” looks, you could see “Find Rules for vms” task.

Notes:
-For the sake of simplicity, I have hard-coded some values and simplified the code, please make changes as per your requirement.
-I have added required documentation inside above code itself.
-This code follows mostly python 2.7.x version, please make minor changes to work with python 3.x

If you need any help, please let me know and yes, please stay tuned for my upcoming blog posts on pyVmomi.

vCenter Server 6.0U3c is live now: Some of cool improvements on Storage DRS

Today vCenter Server 6.0U3c is released. As per me, though this release is a patch release but looks like lot of improvements done on various vCenter/ESXi components. I had an opportunity to work on some of Storage DRS issues and I thought to share those with you. In fact, there are multiple improvements done from Storage DRS perspective but I am sharing some of very interesting ones. Below is the content from release notes with respect to Storage DRS.

1. Storage DRS might place the thin provisioned disks into one datastore, instead of distributing them evenly

During the initial placement of thin provisioned disks, the Storage Distributed Resource Scheduler (SDRS) might miscalculate the entitled space requirement by excluding the reserved space. As a result, SDRS might use only the committed megabytes for the entitled space calculation, causing a wrong placement recommendation on one datastore, instead of distributing them evenly. This issue is resolved in this release.

2. Storage DRS generates only one suitable datastore for initial virtual machine placement

In case there are virtual machines with Raw Device Mapping (RDM) virtual disks, the Storage DRS might consider the actual mapping file size instead of the pointer file size, even though it does not consume any disk space. As a result, the Storage DRS might generate only one suitable datastore when creating new virtual machines. This issue is resolved in this release.

3.vCenter Server might fail in attempt to create a virtual machine on a Storage DRS cluster using script with null CPU or Mem Share values

vCenter Server might fail if you attempt to create a virtual machine on a Storage DRS cluster using a script with null CPU or Mem Share values in a RecommendDatastores() API call. This issue is resolved in this release.

Based on above info, you might have got the high level insights on these Storage DRS improvements. If you ask me, all are really good improvements from Storage DRS perspective. In my future blog posts, I will have deep dive into each of the above issues.

I think, if you are using Storage DRS, it is one of the great reasons to upgrade your environment (apart from important fixes on other vCenter/ESXi areas)

Important links

Download vCenter Server 6.0U3c bits here

vCenter server 6.0 U3c release notes

Yes, there is corresponding ESXi release, please take a look at this KB

It seems, there are some great improvements made to VMware vSAN as well, please take a look at this KB

Configure and Audit Latency Sensitivity enabled VMs on vSphere using vSphere API

Recently I had an opportunity to work on “Latency sensitivity feature” which was introduced in vSphere 5.5 release. This feature is one of the reasons why mission critical VMs can be run on vSphere infrastructure or vSphere enabled clouds. In this blog post, my focus is on sharing how we can configure and audit latency sensitivity enabled VMs using vSphere Java SDK. Before looking into Java SDK scripts, lets understand what is this feature in brief. Latency sensitivity feature can be enabled per VM level (From vSphere web client >> Manage >> VM options >> Latency sensitivity set to high), this feature enables vSphere admin to allocate exclusive access to physical resources for the VM, reserving 100% vCPU time ensures that exclusive PCPU access to the VM. Once vCPU time is reserved (in MHz), this features requires to reserve 100% of the VM memory. 100% memory reservation ensures memory availability for the VM, in other words, memory will not be reclaimed (in case of memory contention) from the VM as it is 100% reserved. Overall, this feature enables vSphere Admin to bypass/tune the virtualization layer and have exclusive access to the hosts physical resources. For more details on this feature I highly recommend to read this official whitepaper

So now we understood that, in order to properly configure latency sensitive VMs, admin not only needs to enable this feature but also reserve 100% of vCPU time in Mhz and 100% memory. Setting memory reservation equal to VMs configured memory is straight-forward but what about allocating vCPU time (in Mhz)? How to set proper vCPU reservation? Lets consider one example: Lets say ESXi host’s PCPU speed is 2.5 Ghz (2500 Mhz) per core. Now if your VM has 2 vCPU configured, vCPU reservation must be 2*2500=5000 Mhz i.e. Number of vCPUs*PCPU speed per core. Similarly we need to follow for any number of vCPU configured per VM. There is one more interesting point i.e. vSphere DRS interop with Latency sensitivity enabled VMs. When such VM is there inside vSphere DRS enabled cluster, one VM-Host soft rule gets created internally(not visible from Web client) with such VM and the host on which this VM is currently residing. As rule is soft, if needed (in case of imbalanced cluster) DRS can violate this rule and migrate this VM to another host. As soon as DRS migrates this VM to another host, earlier rule gets deleted automatically and new rule gets created with new host. You may ask why is this rule gets created internally. Purpose is to avoid vMotion (by DRS) of such latency sensitive VM as much as possible as vMotion can lead to performance impact though its low. (Pass-through with latency sensitive VMs can be leveraged as well, this is explained very well in above pointed white paper)

Now lets take a look at Java SDK scripts. There are 2 Java SDK scripts, one is to configure LS VM and another is for auditing all the LS enabled VMs.

1. Script to configure latency sensitivity feature on the VM

Same script can be found on VMware’s sample exchange or on my git hub account here


//:: # Author: Vikas Shitole
//:: # Website: www.vThinkBeyondVM.com
//:: # Product/Feature: vCenter Server/Latency Sensitivity of the VM(Exclusive pCPU-vCPU affinity)
//:: # Description: Script to configure latency sensitivity feature on the VM and getting list of VMs where LS is configured.
//:# How to run this sample: http://vthinkbeyondvm.com/getting-started-with-yavi-java-opensource-java-sdk-for-vmware-vsphere-step-by-step-guide-for-beginners/
//:# Reference: http://www.vmware.com/files/pdf/techpaper/latency-sensitive-perf-vsphere55.pdf

package com.vmware.yavijava;

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import com.vmware.vim25.InvalidProperty;
import com.vmware.vim25.LatencySensitivity;
import com.vmware.vim25.LatencySensitivitySensitivityLevel;
import com.vmware.vim25.ResourceAllocationInfo;
import com.vmware.vim25.RuntimeFault;
import com.vmware.vim25.TaskInfoState;
import com.vmware.vim25.VirtualHardware;
import com.vmware.vim25.VirtualMachineConfigSpec;
import com.vmware.vim25.mo.Folder;
import com.vmware.vim25.mo.HostSystem;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ManagedEntity;
import com.vmware.vim25.mo.ServiceInstance;
import com.vmware.vim25.mo.Task;
import com.vmware.vim25.mo.VirtualMachine;
import com.vmware.vim25.mo.util.MorUtil;

public class ConfigLatencySensitivity {

public static void main(String[] args) throws InvalidProperty,
RuntimeFault, RemoteException, MalformedURLException {

if(args.length!=5)
{
System.out.println("Usage: Java ConfigLatencySensitivity vCurl username password hostname/IP VMName");
System.exit(-1);
}

URL url = null;
try
{
url = new URL(args[0]);
} catch ( MalformedURLException urlE)
{
System.out.println("The URL provided is NOT valid. Please check it.");
System.exit(-1);
}

ServiceInstance si = new ServiceInstance(new URL(args[0]), args[1],
args[2], true); // Pass 3 argument as vCenterIP/username/password

String VMHost=args[3]; //Host on which VM is resided
String VMToBeConfigured=args[4]; //VM name to be configured.

Folder rootFolder = si.getRootFolder();
VirtualMachine vm1 = (VirtualMachine) new InventoryNavigator(rootFolder)
.searchManagedEntity("VirtualMachine", VMToBeConfigured);

HostSystem host = (HostSystem) new InventoryNavigator(rootFolder)
.searchManagedEntity("HostSystem", VMHost);

//Check how many Mhz CPU can be reserved per vCPU of the VM
int cpuMhz=host.getSummary().getHardware().getCpuMhz();
System.out.println("cpuMHz that can be reserved per vCPU::"+cpuMhz);

//Get RAM and vCPU configured to VM while creating that VM
VirtualHardware vHw=vm1.getConfig().getHardware();
int vmMem=vHw.getMemoryMB();
System.out.println("RAM of the VM " +vm1.getName()+" ::"+vmMem);
int vCpu=vHw.getNumCPU();
System.out.println("Number of vCPUs configured on VM "+vm1.getName()+ " are::"+ vCpu);

VirtualMachineConfigSpec vmSpec=new VirtualMachineConfigSpec();

//Set the latency sensitive level flag to "high"
LatencySensitivity ls=new LatencySensitivity();
ls.setLevel(LatencySensitivitySensitivityLevel.high);
vmSpec.setLatencySensitivity(ls);

// It is highly recommended to reserve the CPU in Mhz equal to Multiples of vCPU
ResourceAllocationInfo cpuAlloc=new ResourceAllocationInfo();
cpuAlloc.setReservation((long) (vCpu*cpuMhz));
vmSpec.setCpuAllocation(cpuAlloc);

//It is highly recommended to reserve the memory equal to RAM of the VM
ResourceAllocationInfo memAlloc=new ResourceAllocationInfo();
memAlloc.setReservation((long) vmMem);
vmSpec.setMemoryAllocation(memAlloc);

//Reconfigure the VM and check reconfigure task status
Task task=vm1.reconfigVM_Task(vmSpec);
System.out.println("Reconfigure Task started ......");

//Wait till task is either queued or running, that will help us to verify whether task is successful or not
while(task.getTaskInfo().getState().equals(TaskInfoState.queued)||task.getTaskInfo().getState().equals(TaskInfoState.running) ){
System.out.println(task.getTaskInfo().getState());
}
if(task.getTaskInfo().getState().equals(TaskInfoState.success))
{
System.out.println("Latency sensitive feature is enabled on the VM "+vm1.getName()+" successfully");
}else{

System.out.println("Latency sensitive feature is NOT enabled on the VM "+vm1.getName()+" successfully");
}

//List of VMs with latency sensitivity enabled will be printed for reference.
System.out.println("==============================================================");
System.out.println("List of VMs where Latency sensitivity feature is enabled");
System.out.println("==============================================================");
ManagedEntity[] vms = new InventoryNavigator(rootFolder).searchManagedEntities("VirtualMachine");
for(ManagedEntity vm:vms){
VirtualMachine vmMo = (VirtualMachine) MorUtil
.createExactManagedEntity(si.getServerConnection(), vm.getMOR());
if(vmMo.getConfig().getLatencySensitivity().getLevel().equals(LatencySensitivitySensitivityLevel.high)){

System.out.println(vmMo.getName());
}
}

si.getServerConnection().logout();
}

}

2. Script to audit Latency sensitivity feature configuration on all the VMs in a vCenter Server.

Same script can be found on VMware’s sample exchange or on my git hub repo here

//:: # Author: Vikas Shitole
//:: # Website: www.vThinkBeyondVM.com
//:: # Product/Feature: vCenter Server/Latency Sensitivity of the VM(Exclusive pCPU-vCPU affinity)
//:: # Description: Script to audit Latency sensitivity feature configuration on all the VMs in a vCenter Server.
//:# How to run this sample: http://vthinkbeyondvm.com/getting-started-with-yavi-java-opensource-java-sdk-for-vmware-vsphere-step-by-step-guide-for-beginners/
//:# Reference: http://www.vmware.com/files/pdf/techpaper/latency-sensitive-perf-vsphere55.pdf

package com.vmware.yavijava;

import java.util.HashMap;
import java.util.Map;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import com.vmware.vim25.InvalidProperty;
import com.vmware.vim25.LatencySensitivitySensitivityLevel;
import com.vmware.vim25.RuntimeFault;
import com.vmware.vim25.VirtualHardware;
import com.vmware.vim25.VirtualMachineConfigInfo;
import com.vmware.vim25.mo.Folder;
import com.vmware.vim25.mo.HostSystem;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ManagedEntity;
import com.vmware.vim25.mo.ServiceInstance;
import com.vmware.vim25.mo.VirtualMachine;
import com.vmware.vim25.mo.util.MorUtil;

public class AuditLatencySensitivityConfig {

public static void main(String[] args) throws InvalidProperty,
RuntimeFault, RemoteException, MalformedURLException {

if(args.length!=3)
{
System.out.println("Usage: Java AuditLatencySensitivityConfig vCurl username password ");
System.exit(-1);
}

URL url = null;
try
{
url = new URL(args[0]);
} catch ( MalformedURLException urlE)
{
System.out.println("The URL provided is NOT valid. Please check it.");
System.exit(-1);
}
String username = args[1]; //vCenter username
String password = args[2]; //vCenter password

// Initialize the system, set up web services

ServiceInstance si = new ServiceInstance(url, username,
password, true); // Pass 3 argument as vCenter URL/username/password

Folder rootFolder = si.getRootFolder();
System.out.println("===========================================================================================");
System.out.println("Auditing configuration of Latency Sensitivity Enabled VMs");
System.out.println("Audit criteria:");

System.out.println("1. VM with LS level set to high should have CPU reservation in multiples of vCPU configured");
System.out.println("2. VM with LS level set to high should have memory reservation equal to VM RAM");
System.out.println("===========================================================================================");

//Maps to store VMs with LS configured and mis-configured
Map lsConfiguredVms=new HashMap();
Map
lsMisConfiguredVms=new HashMap();

//Getting all the hosts available in vCenter Server inventory
ManagedEntity[] hosts = new InventoryNavigator(rootFolder).searchManagedEntities("HostSystem");

//Iterating through 1 host at a time as follows
for(ManagedEntity host1 :hosts){

HostSystem host = (HostSystem) MorUtil
.createExactManagedEntity(si.getServerConnection(), host1.getMOR());

//Check how many Mhz CPU can be reserved per vCPU wrt specified host
int cpuMhz=host.getSummary().getHardware().getCpuMhz();

//Getting all the VMs available on the host
ManagedEntity[] vms = new InventoryNavigator(host).searchManagedEntities("VirtualMachine");
if(vms!=null){
//Iterating through each and very VMs available on perticular host
for(ManagedEntity vm:vms){
VirtualMachine vmMo = (VirtualMachine) MorUtil
.createExactManagedEntity(si.getServerConnection(), vm.getMOR());

//Check whether latency sensitivity property set on the hosts or not
if(vmMo.getConfig().getLatencySensitivity().getLevel().equals(LatencySensitivitySensitivityLevel.high)){
VirtualHardware vHw=vmMo.getConfig().getHardware();
int vmMem=vHw.getMemoryMB(); //RAM of the VM
int vCpu=vHw.getNumCPU(); //vCPUs configured to the VM
VirtualMachineConfigInfo vmConfigInfo=vmMo.getConfig();
long cpuReservation=vmConfigInfo.getCpuAllocation().getReservation(); //CPU reservation on the VM
long memReservation=vmConfigInfo.getMemoryAllocation().getReservation(); //Memory reservation on the VM

//Compare mem/cpu reservation wrt configured memory/vCPUs on the host
if((cpuReservation==(vCpu*cpuMhz))&&(memReservation==vmMem)){
lsConfiguredVms.put(vmMo.getName(),host.getName());
}else{
lsMisConfiguredVms.put(vmMo.getName(),host.getName());
}
}
}
}else{
System.out.println("NO VMs available on the specified host");
}
}
System.out.println("VM list where Latency sensitivity is configured properly");
System.out.println("-------------------------------------------------------------");
for (Map.Entry< String , String> lsConfiguredVm : lsConfiguredVms.entrySet()) {
System.out.println("[" + lsConfiguredVm.getKey() + "::" + lsConfiguredVm.getValue()
+ "]");
}
System.out.println("\n VM list where Latency sensitivity is NOT configured properly");
System.out.println("-------------------------------------------------------------");
for (Map.Entry< String , String> lsMisConfiguredVm : lsMisConfiguredVms.entrySet()) {
System.out.println("[" + lsMisConfiguredVm.getKey() + "::" + lsMisConfiguredVm.getValue()
+ "]");
}
si.getServerConnection().logout();
}
}

Let me know if you need any help on this. If you have still not setup your YAVI JAVA Eclipse environment:Getting started tutorial Important tutorials to start with: Part I & Part II

Want to vMotion a VM from one vCenter server to another vCenter using vSphere API? Here you go

As part of one of customers case, I was testing vMotion across two 6.0 vCenter servers those are connected to the same SSO domain. As we know already, when 2 vCenter servers are connected to the same SSO domain, you can manage both VCs using web client. Initially I tested vMotion from web client and later in order to automate bulk VMs migration across vCenter, I was looking for vSphere APIs and I could find below 2 vSphere APIs.

1. RelocateVM_Task() under VirtualMachine Managed object
2. placevm() under ClusterComputeResource managed object

I went through above vSphere API reference and I could see RelocateVM_Task() API was already there. However, in vSphere 6.0, it is improved greatly in order to support vMotion between 2 vCenters. On the other hand, placeVM() API was new brand API introduced in vSphere 6.0. Initially, I decided to try RelocateVM_Task() API for automating vMotion across 2 vCenters with same SSO domain. After automating this, I tested my java SDK script on vCenters with same SSO domain and it worked with no any issues. Later, I just thought lets give a try across vCenters those are connected to the different SSO domains and to my surprise, it worked like charm. is it not super cool? How easy it is now to migrate your workloads across data-centers/VCs/Clusters!.

So vMotion between 2 completely different vCenter is supported in vSphere 6.0 but there is NO UI support from web client at the moment. If you want to this functionality i.e. vMotion between 2 VCs with different SSO domains. vSphere API is the only way.

After successful vMotion across different SSO domains, I was really excited and thought to play with this little more by creating a DRS cluster in both VCs. I created a VM-VM affinity rule with couple of VMs in DRS cluster in VC1 as shown in below screenshot.

VC1_Rule_before_vMotion

Now I initiated vMotion from first VC to DRS cluster in second VC using same Java SDK script and I could see the DRS rule associated the migrated VM also got migrated as shown in below screen shot. How cool is that!

VC2_Rule_After_vMotion

Below is the complete code sample which can help you quickly to vMotion from a VC to other VC.

Note that this sample works fine with VCs with same SSO or VCs with different SSO. You do not even need to have shared storage between both VCs. This script will work fine within the same VC as well (with some change).

Same script is available on my git hub repository: ExVC_vMotion.java


//:: # Author: Vikas Shitole
//:: # Website: www.vThinkBeyondVM.com
//:: # Product/Feature: vCenter Server/DRS/vMotion
//:: # Description: Extended Cross VC vMotion using RelocateVM_Task() API. vMotion between vCenters (with same SSO domain or different SSO domain)

package com.vmware.yavijava;

import java.net.MalformedURLException;
import java.net.URL;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.ServiceLocator;
import com.vmware.vim25.ServiceLocatorCredential;
import com.vmware.vim25.ServiceLocatorNamePassword;
import com.vmware.vim25.VirtualDevice;
import com.vmware.vim25.VirtualDeviceConfigSpec;
import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
import com.vmware.vim25.VirtualDeviceDeviceBackingInfo;
import com.vmware.vim25.VirtualEthernetCard;
import com.vmware.vim25.VirtualMachineMovePriority;
import com.vmware.vim25.VirtualMachineRelocateSpec;
import com.vmware.vim25.mo.ClusterComputeResource;
import com.vmware.vim25.mo.Datastore;
import com.vmware.vim25.mo.Folder;
import com.vmware.vim25.mo.HostSystem;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ServiceInstance;
import com.vmware.vim25.mo.VirtualMachine;

public class ExVC_vMotion {

public static void main(String[] args) throws Exception {
if(args.length!=7)
{
//Parameters you need to pass
System.out.println("Usage: ExVC_vMotion srcVCIP srcVCusername srcVCpassword destVCIP destVCusername destVCpassword destHostIP");
System.exit(-1);
}

URL url1 = null;
try
{
url1 = new URL("https://"+args[0]+"/sdk");
} catch ( MalformedURLException urlE)
{
System.out.println("The URL provided is NOT valid. Please check it.");
System.exit(-1);
}

String srcusername = args[1];
String srcpassword = args[2];
String DestVC=args[3];
String destusername=args[4];
String destpassword = args[5];
String destvmhost=args[6];

//Hardcoded parameters for simplification
String vmName="VM1"; //VM name to be migrated
String vmNetworkName="VM Network"; //destination vSphere VM port group name where VM will be migrated
String destClusterName="ClusterVC2"; //Destination VC cluster where VM will be migrated
String destdatastoreName="DS1"; //destination datastore where VM will be migrated
String destVCThumpPrint="c7:bc:0c:a3:15:35:57:bd:fe:ac:60:bf:87:25:1c:07:a9:31:50:85"; //SSL Thumbprint (SHA1) of the destination VC

// Initialize source VC
ServiceInstance vc1si = new ServiceInstance(url1, srcusername,
srcpassword, true);
URL url2 = null;
try
{
url2 = new URL("https://"+DestVC+"/sdk");
} catch ( MalformedURLException urlE)
{
System.out.println("The URL provided is NOT valid. Please check it.");
System.exit(-1);
}

// Initialize destination VC

ServiceInstance vc2si = new ServiceInstance(url2, destusername,
destpassword, true);
Folder vc1rootFolder = vc1si.getRootFolder();
Folder vc2rootFolder = vc2si.getRootFolder();

//Virtual Machine Object to be migrated
VirtualMachine vm = null;
vm = (VirtualMachine) new InventoryNavigator(vc1rootFolder)
.searchManagedEntity("VirtualMachine", vmName);

//Destination host object where VM will be migrated
HostSystem host = null;
host = (HostSystem) new InventoryNavigator(vc2rootFolder)
.searchManagedEntity("HostSystem", destvmhost);
ManagedObjectReference hostMor=host.getMOR();

//Destination cluster object creation
ClusterComputeResource cluster = null;
cluster = (ClusterComputeResource) new InventoryNavigator(vc2rootFolder)
.searchManagedEntity("ClusterComputeResource", destClusterName);

//Destination datastore object creation
Datastore ds=null;
ds = (Datastore) new InventoryNavigator(vc2rootFolder)
.searchManagedEntity("Datastore", destdatastoreName);
ManagedObjectReference dsMor=ds.getMOR();

VirtualMachineRelocateSpec vmSpec=new VirtualMachineRelocateSpec();
vmSpec.setDatastore(dsMor);
vmSpec.setHost(hostMor);
vmSpec.setPool(cluster.getResourcePool().getMOR());

//VM device spec for the VM to be migrated
VirtualDeviceConfigSpec vdcSpec=new VirtualDeviceConfigSpec();
VirtualDevice[] devices= vm.getConfig().getHardware().getDevice();
for(VirtualDevice device:devices){

if(device instanceof VirtualEthernetCard){

VirtualDeviceDeviceBackingInfo vddBackingInfo= (VirtualDeviceDeviceBackingInfo) device.getBacking();
vddBackingInfo.setDeviceName(vmNetworkName);
device.setBacking(vddBackingInfo);
vdcSpec.setDevice(device);
}

}

vdcSpec.setOperation(VirtualDeviceConfigSpecOperation.edit);
VirtualDeviceConfigSpec[] vDeviceConSpec={vdcSpec};
vmSpec.setDeviceChange(vDeviceConSpec);

//Below is code for ServiceLOcator which is key for this vMotion happen
ServiceLocator serviceLoc=new ServiceLocator();
ServiceLocatorCredential credential=new ServiceLocatorNamePassword();
((ServiceLocatorNamePassword) credential).setPassword(destpassword);
((ServiceLocatorNamePassword) credential).setUsername(destusername);
serviceLoc.setCredential(credential);

String instanceUuid=vc2si.getServiceContent().getAbout().getInstanceUuid();
serviceLoc.setInstanceUuid(instanceUuid);
serviceLoc.setSslThumbprint(destVCThumpPrint);
serviceLoc.setUrl("https://"+DestVC);
vmSpec.setService(serviceLoc);
System.out.println("VM relocation started....please wait");
boolean flag=false;
vm.relocateVM_Task(vmSpec, VirtualMachineMovePriority.highPriority);
flag=true;
if(flag){
System.out.println("VM is relocated to 2nd vCenter server");
}
vc1si.getServerConnection().logout();
vc2si.getServerConnection().logout();
}
}

Notes:
– There is one imp parameter you need to pass into migration spec i.e. Destination VC Thumbprint. There are several ways to get it as shown here. I personally used below way to get the destination VC thumbprint.
From google chrome browser : URL box of the VC (besides https:// lock symbol)>>view site information >> Certificate information >> Details >> Scroll down till last as shown in below screenshot

Thumbprint

– For the sake of simplicity, I have hard-coded some parameters, you can change it based on your environment.
– You can scale the same code to vMotion multiple VMs across vCenter server
– As I said, there is another API for vMotion across VCs i.e. placevm() under ClusterComputeResource managed object . Please stay tuned for my next blog post on the same.

If you want to automate the same use case using PowerCLI, here is great post by William Lam.

If you have still not setup your YAVI JAVA Eclipse environment:Getting started tutorial

Important tutorials to start with: Part I & Part II