Programming / Scripting Language used for vSphere Management
Incorrect VirtualDisk.NumberWriteAveraged from QueryAvailableMetric
I've recently been looking over some of the data collected by QueryAvailablePerfMetrics, and I came across some inconsistent data regarding the Disk Write IO metrics, specifically for Virtual Disks - "virtualdisk.numberwriteaveraged.average"
I'm seeing values 50-100x what I see in vCenter - I see around 120 max in the performance graph for virtual disks (customized to show number write average) when doing a test of writing from /dev/random to a file, but the API reports 12000+ (not exactly 100x). Interestingly enough, when I do a iostat on the VM and monitor write rate, I don't see it going past 30, which makes me wonder what these numbers mean.
I'm calling the API (https://pubs.vmware.com/vi3/sdk/ReferenceGuide/vim.PerformanceManager.html#queryAvailableMetric) using entity = a VM MOR, start time = current time - 1hr, end time = 1hr, interval = PerformanceManagerSummary::getRefreshRate (https://www.vmware.com/support/developer/converter-sdk/conv61_apireference/vim.PerformanceManager.ProviderSummary.html#refreshRate)
Am I calling the API wrong? Or just misunderstanding the metrics?
Determining capacity of PCIeSSDs that are PassthruActive
Hi everyone!
I have some PCIeSSDs that are being used as DirectPath I/O devices for my VMs.
While they are in this configuration there doesn't seem to be any way (at the vSphere-level) to determine storage information like their capacity or their storage adapter name. I feel like I've exhausted every path in the MOB and can't find anything beyond their bus location and their PCI class ID.
Is there something I am missing? Or is this just what happens when these devices are configured for DirectPath I/O?
Thanks in advance for any guidance ya'll can provide!
VirtualDisk VDiskId always null
I'm trying to use the VcenterVStorageObjectManager ExtendDisk_Task operation to extend a virtual machine's virtual disk to 30GB, but for the VirtualDisk device it seems that the VDiskId property is always returned as null no matter which VM or disk try it on. I'm not sure why that is, we are running 6.5 on all hosts and VCSA and all VMs are VM version 13. The code seems pretty straightforward if I could figure out why VDiskId doesn't seem to be populating. Does anyone have any ideas? Useful information on using the virtual disk manager seems pretty scarce from what I can find searching
VcenterVStorageObjectManager vDiskMan = (VcenterVStorageObjectManager)vimClient.GetView(vimClient.ServiceContent.VStorageObjectManager, null); VirtualDevice[] devices = vm.Config.Hardware.Device; VirtualDisk vd = null; foreach (VirtualDevice device in devices) { device.DeviceInfo.Label.Equals("Hard disk 1")) { vd = (VirtualDisk)device; VirtualDiskFlatVer2BackingInfo backInfo = (VirtualDiskFlatVer2BackingInfo)vd.Backing; //vd.VDiskId always reports null vDiskMan.ExtendDisk_Task(vd.VDiskId, backInfo.Datastore, 30720); } }
Questions on Virtual Disk's UUID
Hi all,
The API reference does not have much description about Virtual Disk UUID and so I would like to ask couple of questions.
I am referring to the UUID we can retrieve from Virtual Disk's BackingInfo (virtualmachine.config.hardware.device[xxxx].backing.uuid)
1. Is this UUID unique within the vCenter Server?
2. If a disk is detached from the one VM and then attached to another VM, is this UUID guaranteed to remain the same? Assuming that the Virtual Disk's vmdk files were not altered.
Thanks.
Find associated datastore from VM C# sdk
Hi,
Is anyone able to tell me how to find all Vm details from the VM name in c# using VMWare.Vim.dll ?
I found how to find host but not datastore for example.
I searched in all properties of VM and datastore but could not find how to see the relationship between them.
My code for VM and how to link it to vmware host :
System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => { return true; };
VimClient vimClient = new VimClientImpl();
ServiceContent vimServiceContent = new ServiceContent();
string sViServer = "<ViServerIPAddress>";
string sUsername = "<AdminVsphere>";
string sPassword = "<Password>";
vimClient.Connect("https://" + sViServer + "/sdk");
vimClient.Login(sUsername, sPassword);
vimServiceContent = vimClient.ServiceContent;
NameValueCollection filter = new NameValueCollection();
IList<VMware.Vim.EntityViewBase> vmList = vimClient.FindEntityViews(typeof(VirtualMachine), null, filter, null);
foreach (VirtualMachine vm in vmList)
{
Console.WriteLine(vm.Name);
VMware.Vim.CustomFieldValue[] VmValues = vm.Value;
foreach (VMware.Vim.CustomFieldValue VmValue in VmValues)
{
Console.WriteLine(VmValue.Key.ToString());
}
HostSystem host = (HostSystem)vimClient.GetView(vm.Runtime.Host, null);
Console.WriteLine(host.Name);
ManagedObjectReference[] DsList = vm.Datastore;
foreach (ManagedObjectReference Ds in DsList)
{
Console.WriteLine(Ds.Type);
Console.WriteLine(Ds.Value);
}
}
For Datastores, i have this :
IList<VMware.Vim.EntityViewBase> DatastoreList = vimClient.FindEntityViews(typeof(Datastore), null, filter, null);
foreach (Datastore Datastore in DatastoreList)
{
Console.WriteLine(Datastore.Name);
Console.WriteLine(Datastore.Value);
ManagedObjectReference[] Vms = Datastore.Vm;
foreach (ManagedObjectReference Vm in Vms)
{
Console.WriteLine(Vm.Type);
Console.WriteLine(Vm.Value);
}
DatastoreHostMount[] Hosts = Datastore.Host;
foreach (DatastoreHostMount host in Hosts)
{
Console.WriteLine(host.Key);
}
}
But no value permits me to link an existing datastore to an existing VM.
Could you help me plz ?
Fred
How to find datastore of a VM from VM Name - VMWare.Vim.dll - C#
Hi,
Is there anyone that can tell me how to find vm details from the VM Name in C# ?
I tried using VMWare.Vim.dll but could not link existing datastore properties to an existing VM.
For VM, i could link the host of the VM with the following code but no more :
System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => { return true; };
VimClient vimClient = new VimClientImpl();
ServiceContent vimServiceContent = new ServiceContent();
string sViServer = "<VcenterIpAddress>";
string sUsername = "<VcenterAdminLogin>";
string sPassword = "<VcenterAdminPasswd>";
vimClient.Connect("https://" + sViServer + "/sdk");
vimClient.Login(sUsername, sPassword);
vimServiceContent = vimClient.ServiceContent;
NameValueCollection filter = new NameValueCollection();
IList<VMware.Vim.EntityViewBase> vmList = vimClient.FindEntityViews(typeof(VirtualMachine), null, filter, null);
foreach (VirtualMachine vm in vmList)
{
Console.WriteLine(vm.Name);
VMware.Vim.CustomFieldValue[] VmValues = vm.Value;
foreach (VMware.Vim.CustomFieldValue VmValue in VmValues)
{
Console.WriteLine(VmValue.Key.ToString());
}
HostSystem host = (HostSystem)vimClient.GetView(vm.Runtime.Host, null);
Console.WriteLine(host.Name);
ManagedObjectReference[] DsList = vm.Datastore;
foreach (ManagedObjectReference Ds in DsList)
{
Console.WriteLine(Ds.Type);
Console.WriteLine(Ds.Value);
}
}
For Datastore, i have the following code but no link between the two parts of code :
IList<VMware.Vim.EntityViewBase> DatastoreList = vimClient.FindEntityViews(typeof(Datastore), null, filter, null);
foreach (Datastore Datastore in DatastoreList)
{
Console.WriteLine(Datastore.Name);
Console.WriteLine(Datastore.Value);
ManagedObjectReference[] Vms = Datastore.Vm;
foreach (ManagedObjectReference Vm in Vms)
{
Console.WriteLine(Vm.Type);
Console.WriteLine(Vm.Value);
}
DatastoreHostMount[] Hosts = Datastore.Host;
foreach (DatastoreHostMount host in Hosts)
{
Console.WriteLine(host.Key);
}
}
If no solution i'll use a powercli script, but i would like to have all in c#.
Could you help me plz ?
Fred
Vsphere Automation rest API
why CustomizationIPSettings not setNicSettingMap method?
vsphere web service sdk 6.7
public static CustomizationSpec createCustomizations(){
CustomizationSpec spec=new CustomizationSpec();
//创建文件类型windows
CustomizationWinOptions options = new CustomizationWinOptions();
options.setChangeSID(true);
options.setDeleteAccounts(false);
spec.setOptions(options);
//创建应答文件
CustomizationSysprep sysprep=new CustomizationSysprep();
//
CustomizationGuiUnattended unattended=new CustomizationGuiUnattended();
unattended.setTimeZone(4);
unattended.setAutoLogon(false);
unattended.setAutoLogonCount(0);
sysprep.setGuiUnattended(unattended);
CustomizationUserData userData=new CustomizationUserData();
userData.setFullName("viuxan.com");
userData.setOrgName("vixuan.com");
CustomizationVirtualMachineName virtualMachineName=new CustomizationVirtualMachineName();
userData.setComputerName(virtualMachineName);
userData.setProductId("HWRFF-2FFYX-XFXP2-DYFC3-BX3B7");
sysprep.setUserData(userData);
CustomizationIdentification identification=new CustomizationIdentification();
identification.setJoinWorkgroup("WORKGROUP");
sysprep.setIdentification(identification);
spec.setIdentity(sysprep);
CustomizationGlobalIPSettings globalIPSettings=new CustomizationGlobalIPSettings();
spec.setGlobalIPSettings(globalIPSettings);
//设置IP地址
CustomizationAdapterMapping[] adapterMappings =new CustomizationAdapterMapping[1];
CustomizationIPSettings ipSetting=new CustomizationIPSettings();
//重新设置自定义规范 IP 地址
//设置dns
String[] dnss=new String[1];
dnss[0]="8.8.8.8";
//ipSetting.setDnsServerList(dnss);
//设置gateway
String[] gateways=new String[1];
gateways[0]="192.168.0.1";
ipSetting.setGateway(gateways);
//设置子网掩码
String subnetMask="255.255.255.0";
ipSetting.setSubnetMask(subnetMask);
// 设置IP地址
CustomizationFixedIp ip=new CustomizationFixedIp();
ip.setIpAddress("192.168.0.111");
ipSetting.setIp(ip);
CustomizationAdapterMapping adapter=new CustomizationAdapterMapping();
adapter.setAdapter(ipSetting);
adapterMappings[0]=adapter;
spec.setNicSettingMap(adapterMappings);
CustomizationSpecItem customizationSpecItem=new CustomizationSpecItem();
customizationSpecItem.setSpec(spec);
CustomizationSpecInfo info=new CustomizationSpecInfo();
info.setName("123456");
info.setDescription("123456");
customizationSpecItem.setInfo(info);
return spec;
}
error:
The method setNicSettingMap(CustomizationAdapterMapping[]) is undefined for the type CustomizationSpec!
Issue with Remote Console over API after upgrade from vCenter 6.5U1 to vCenter 6.5U2
Hi,
We have issue with opening Remote Console over API after upgrade vCenter to 6.5 U2e from 6.5 U1g. On vCenter 6.5 U1g everything worked fine. Remote Console works fine from vCenter server 6.5 U2e over vphere web client at this time but over API not. Does anybody know if there is any new changes in API?
There is shown some unknow "clientId" in log file (vsphere_client_virgo.log).
#########################################
root@vcenter [ /var/log/vmware/vsphere-client/logs ]# tail -f vsphere_client_virgo.log
[
[2019-04-12T11:37:34.946Z] [INFO ] http-bio-9443-exec-2 70012361 ###### ###### com.vmware.vise.util.session.SessionUtil Generated hashed session id: 101340
[2019-04-12T11:37:35.285Z] [ERROR] http-bio-9443-exec-2 o.a.c.c.C.[.[localhost].[/vsphere-client].[AuthdAdapter] Servlet.service() for servlet [AuthdAdapter] in context with path [/vsphere-client] threw exception java.lang.RuntimeException: java.lang.IllegalStateException: There's no clientId in the session
at com.vmware.vise.vim.commons.mks.tomcat.TomcatAuthdAdapterServlet.doGet(TomcatAuthdAdapterServlet.java:142)
###########################################
Thanks
Ondrej
How do get maxTotalLatency data
Can anyone explain why Performance Metric Keys differ in Deployments
In the process of monitoring Datastores, we track the total Read and Write latency of Datastores.
Historically speaking, we would use performance metric keys 182 and 183.
Based on a bit of code that queries all the performance keys and spits them out to console, I can see the following in one environment:
182: datastore, totalReadLatency
183: datastore, totalWriteLatency
However, when I go into another vSphere/ESXi environment, I see this:
339: datastore, totalReadLatency
340: datastore, totalWriteLatency
The performance metric keys are very different.
I'm just trying to understand why or how this happened with the deployments. I've modified our tool to pull the ID to value pairing to use the right one dynamically, but it is a head scratcher as to how this happened in the first place.
Honestly, I'm just looking to see if anyone has encountered something like this to put a rationale or explanation to it.
VIsdk with C++
I am planning to use a C++ client with the VISDk web service. Is this supported ? i did not see any examples for C++ anywhere . So awnted to check
Problems connecting to VI SDK using C++/gsoap-2.7
Hi
I know this topic has been discussed quite a lot recently, but unfortunately I haven't been able to find a solution to my problem. I am currently running ESX Server 3.5. I have no problems accessing it via the SDK using Java and Perl. However, I am trying to get a simple C++ program working that can connect to it and do something useful. First of all, I changed the proxy.xml file on the ESX Server so that the sdk can be accessed via both http and https.
Second, on my client machine (64-bit AMD Athlon running Ubuntu 8.10) I have installed gsoap-2.7 to convert the WSDL files into stubs necessary to communicate with the server. I use the various gsoap programs to convert the vimService.wsdl file in the directory SDK/wsdl/vim/ as follows:
wsdl2h -x -s vimService.wsdl
soapcpp2 -i -C -I/home/ashok/gsoap-2.7/gsoap/import vimService.h
This generates soapH.h, soapStub.h, soapC.cpp, as well as soapVimBindingProxy.{h,cpp}.
Here is my simple test.cpp driver program that tries to access the ESX Server and create a snapshot of one of the VMs (note that I've specified http and not https in the URL):
#include "soapH.h"
#include "VimBinding.nsmap"
#include "soapVimBindingProxy.h"
int main() {
VimBindingProxy service;
service.soap_endpoint = "http://<server ip address>:443/sdk";
ns2__ManagedObjectReference mor;
ns2__CreateSnapshotRequestType req;
_ns2__CreateSnapshotResponse resp;
req._USCOREthis = &mor;
req.name = "ashok_linux_1";
req.memory = false;
req.quiesce = false;
if (service.CreateSnapshot(&req, &resp) == SOAP_OK) {
std::cout << "OK"<< std::endl;
}
else {
std::cout << "BAD" << std::endl;
service.soap_print_fault(stdout);
}
}
I compile this and run as follows:
g++ *.cpp -Wall -DWITH_OPENSSL -lgsoap++
ashok@ashok-desktop: ./a.out
BAD
Error -1 fault: SOAP-ENV:Client
"End of file or no input: Connection reset by peer"
Detail: no detail
The message "Error -1 fault: SOAP-ENV:Client
no subcode" is something that I always get, regardless of the SDK function that I invoke. Has anyone figured out this problem, specifically using the C++ stub functions auto-generated by gsoap? If so, please tell me what I'm doing wrong as I'm close to pulling my hair out!
Ashok
I think I'm going to write up a tutorial for C++ & gsoap to get people started. I got a working setup that will build libraries and use the advanced C++ proxy option. This generates more OO like code that (in my opinion) reads and is easier to code with. I'll post it up in this thread if I do get to it this week.
First thing is you'll need to login first. You won't be able to call most of the functions in the SDK until you do.
You'll also need to keep the compile flags consistent for all the objects. You'll need at least -DWITH_COOKIES. Without cookies you'll end up with permission errors as you end up regenerating a new SessionID for each call.
Can you also post up all the steps in your compile process? It wasn't clear if you compiled and linked in your soapC.
Here's a very simple example you can work from. I don't call a login in this one, but you can use it to get a working program and start to build on it. It does use SSL so you can see how that's handled.
#include "soapVimBindingProxy.h"
#include "VimBinding.nsmap"
#include <time.h>
#include <iostream>
#include <typeinfo>
using namespace std;
void sigpipe_handle(int x) { cout << "sigpipe: " << x << endl; }
int main(int argc, char* argv[])
{
VimBinding vim;
ns1__ManagedObjectReference ManagedObjectRef;
ns1__RetrieveServiceContentRequestType RetrieveServiceContentReq;
_ns1__RetrieveServiceContentResponse RetrieveServiceContentRes;
ns1__ServiceContent *ServiceContent;
ns1__AboutInfo *AboutInfo;
if (argc != 2)
{
cout << "Usage: " << argv[0] << " <service url>" << endl;
exit(1);
}
string service_url(argv[1]);
vim.endpoint = service_url.c_str();
soap_ssl_init();
if (soap_ssl_client_context(
vim.soap,
SOAP_SSL_NO_AUTHENTICATION,
NULL,
NULL,
NULL,
NULL,
NULL ))
{
cout << "SSL:";
soap_print_fault(vim.soap, stderr);
soap_done(vim.soap);
soap_end(vim.soap);
exit(1);
}
ManagedObjectRef.__item = "ServiceInstance";
ManagedObjectRef.type = new string("ServiceInstance");
RetrieveServiceContentReq._USCOREthis = &ManagedObjectRef;
if ( vim.__ns1__RetrieveServiceContent(&RetrieveServiceContentReq, &RetrieveServiceContentRes) == SOAP_OK )
{
cout << "RetrieveServiceContent - OK" << endl;
}
else
{
delete ManagedObjectRef.type;
soap_print_fault(vim.soap,stderr);
soap_done(vim.soap);
soap_end(vim.soap);
exit(1);
}
ServiceContent = RetrieveServiceContentRes.returnval;
if (ServiceContent && ServiceContent->about)
{
AboutInfo = ServiceContent->about;
cout << "fullName: " << AboutInfo->fullName << endl;
cout << " name: " << AboutInfo->name << endl;
cout << " build: " << AboutInfo->build << endl;
cout << " version: " << AboutInfo->version << endl;
cout << " apiType: " << AboutInfo->apiType << endl;
cout << " productLineId: " << AboutInfo->productLineId << endl;
}
delete ManagedObjectRef.type;
soap_done(vim.soap);
soap_end(vim.soap);
return 0;
}
Thank you very much for your response. I am looking forward to reading your C++/gsoap "Getting Started" tutorial. I will try working with the template code you provided, but I first tried adding login capability to my original test program. My program (test.cpp) now looks like this:
#include <cstdlib>
#include <iostream>
#include <string>
#include "soapH.h"
#include "VimBinding.nsmap"
#include "soapVimBindingProxy.h"
int main() {
VimBindingProxy service;
ns2__ManagedObjectReference mor;
service.soap_endpoint = "http://<ip address>:443/sdk";
// Invoke Login API
ns2__LoginRequestType login_request;
_ns2__LoginResponse login_response;
login_request._USCOREthis = &mor;
login_request.userName = "root";
login_request.password = "<my root passwd>";
if (service.Login(&login_request, &login_response) == SOAP_OK) {
std::cout << "login ok" << std::endl;
}
else {
std::cout << "login not ok" << std::endl;
service.soap_print_fault(stdout);
}
// Invoke RetrieveServiceContent API
ns2__RetrieveServiceContentRequestType service_request;
_ns2__RetrieveServiceContentResponse service_response;
service_request._USCOREthis = &mor;
if (service.RetrieveServiceContent(&service_request, &service_response) == SOAP_OK) {
std::cout << "retrieve ok" << std::endl;
}
else {
std::cout << "retrieve not ok" << std::endl;
service.soap_print_fault(stdout);
}
}
This is how I compiled the code:
ashok@ashok-desktop:g++ -DWITH_OPENSSL -DWITH_COOKIES test.cpp soapC.cpp soapVimBindingProxy.cpp /home/ashok/gsoap-2.7/gsoap/stdsoap2.cpp -lssl -lcrypto
Unfortunately, I get both "not ok" messages when I run the executable. Looking at this code, is it obvious to you what I'm not doing correctly?
Thanks
Ashok
You'll need your ServiceContent first. You'll need it for most of the method calls against the SDK and should get it first. You also need to do a bit more setup on the ManagedObject reference.
You should setup the ManagedObjectReference with the "ServiceInstance" string. I updated it below. Call this before the login, you'll need the ServiceContent response for login.
// Invoke RetrieveServiceContent API
ns2__RetrieveServiceContentRequestType service_request;
_ns2__RetrieveServiceContentResponse service_response;
mor.__item = "ServiceInstance";
mor.type = new string("ServiceInstance");
service_request._USCOREthis = &mor;
if (service.RetrieveServiceContent(&service_request, &service_response) == SOAP_OK)
{
std::cout << "retrieve ok" << std::endl;
}
else
{
std::cout << "retrieve not ok" << std::endl;
service.soap_print_fault(stdout);
}
delete mor.type;
The login function is from the SessionManager object, so you'll need that to set up your Login call:
ns2__ServiceContent *ServiceContent;
ServiceContent = service_response.returnval;
// Invoke Login API
ns2__LoginRequestType login_request;
_ns2__LoginResponse login_response;
login_request._USCOREthis = ServiceContent->sessionManager;
login_request.userName = "root";
login_request.password = "<my root passwd>";
if (service.Login(&login_request, &login_response) == SOAP_OK)
{
std::cout << "login ok" << std::endl;
}
else
{
std::cout << "login not ok" << std::endl;
service.soap_print_fault(stdout);
}
I finally got your test program (from your prior post) to build and run properly. Thanks so much for your help! In case anyone is interested, here are the exact sequence of steps I took to get things working. Note that I have installed both gsoap-2.7 and the VI SDK in my home directory /home/ashok:
1) Copy over the vim25 WSDL file:
cp /home/ashok/vi_sdk/SDK/wsdl/vim25/vim.wsdl .
2) Build .h and .cpp files from WSDL:
wsdl2h -o vim25.h vim.wsdl
soapcpp2 -x -C vim25.h -I/home/ashok/gsoap-2.7/gsoap/import
3) Put test program in file test.cpp
4) Build executable:
g++ -DWITH_OPENSSL -DWITH_COOKIES test.cpp soapC.cpp soapClient.cpp /home/ashok/gsoap-2.7/gsoap/stdsoap2.cpp -lssl -lcrypto
5) Run executable
ashok@ashok-desktop:~/vi_gsoap$ ./a.out
https://<ip addr>:443/sdk
RetrieveServiceContent - OK
fullName: VMware ESX Server 3.5.0 build-123630
name: VMware ESX Server
build: 123630
version: 3.5.0
apiType: HostAgent
productLineId: esx
I can use the property collector to get the ManagedObjectReference corresponding to a specific VirtualMachine. However, I'm having trouble getting the MOR corresponding to a snapshot of the VM. Given the name of a VM and the name of a snapshot within the VM, could you please tell me the general algorithm I need to follow to get a hold of the ManagedObjectReference for this snapshot?
Thanks
Ashok
If you're getting your VM ManagedObject from RetrieveProperties, you should also just get the snapshot
property. The currentSnapshot
from this property will have a ManagedObjectReference to the snapshot. You can use this to the snapshot task methods or you can RetrieveProperties again to get the snapshot info.
I might be able to get you some code examples in a bit.
Stumpr
Sorry to bother you with more questions. So I have no problems using the PropertyCollector to iterate over all the VirtualMachine objects. For each VM object, I can easily grab the Snapshot MORs associated with it as well as get info about all the virtual disk files that comprise the VM. What I would like to do now is to use the PropertyCollector to iterate over all the Datastore objects and for each Datastore, find out which VirtualMachines map to the datastore. I took your original traversal code and modified it slightly (I changed the datacenter traversal path and propertyspec type). My changes are marked with ***:
FolderTraversalSelectionSpec.name = new string("FolderTraversalSpec");
DataCenterVMTraversalSelectionSpec.name = new string("DataCenterVMTraversalSpec");
DataCenterVMTraversalSpec.name = new string("DataCenterVMTraversalSpec");
DataCenterVMTraversalSpec.type = "Datacenter";
DataCenterVMTraversalSpec.path = "datastoreFolder"; ***
DataCenterVMTraversalSpec.skip = &xsd_true;
FolderTraversalSpec.name = new string("FolderTraversalSpec");
FolderTraversalSpec.type = "Folder";
FolderTraversalSpec.path = "childEntity";
FolderTraversalSpec.skip = &xsd_true;
DataCenterVMTraversalSpec.selectSet.push_back(&FolderTraversalSelectionSpec);
FolderTraversalSpec.selectSet.push_back(&DataCenterVMTraversalSelectionSpec);
FolderTraversalSpec.selectSet.push_back(&FolderTraversalSelectionSpec);
PropertySpec.type = "Datastore"; ***
PropertySpec.all = &xsd_true; ***
ObjectSpec.obj = ServiceContent->rootFolder;
ObjectSpec.skip = &xsd_true;
ObjectSpec.selectSet.push_back(&FolderTraversalSpec);
ObjectSpec.selectSet.push_back(&DataCenterVMTraversalSpec);
PropertyFilterSpec.propSet.push_back(&PropertySpec);
PropertyFilterSpec.objectSet.push_back(&ObjectSpec);
RetrievePropertiesReq._USCOREthis = ServiceContent->propertyCollector;
RetrievePropertiesReq.specSet.push_back(&PropertyFilterSpec);
When I invoke the RetrieveProperties function:
if ( vim.__ns1__RetrieveProperties(&RetrievePropertiesReq, &RetrievePropertiesRes) == SOAP_OK )
the ESX server responds with a fault:
SOAP 1.1 fault: "":ServerFaultCode
""
Detail:
Is this something you have seen before?
Thanks
Ashok
I don't think there is a folder for the Datastore. You will probably need to just do your call to get the Datacenter object(s) and then enumerate their datastores...using the string "datastoreFolder" is likely the cause of your serverFaultCode.
FolderTraversalSelectionSpec.name = new string("FolderTraversalSpec");
DataCenterVMTraversalSelectionSpec.name = new string("DataCenterVMTraversalSpec");
DataCenterVMTraversalSpec.name = new string("DataCenterVMTraversalSpec");
DataCenterVMTraversalSpec.type = "Datacenter";
DataCenterVMTraversalSpec.path = "vmFolder"; // Change this back
DataCenterVMTraversalSpec.skip = &xsd_true;
FolderTraversalSpec.name = new string("FolderTraversalSpec");
FolderTraversalSpec.type = "Folder";
FolderTraversalSpec.path = "childEntity";
FolderTraversalSpec.skip = &xsd_true;
DataCenterVMTraversalSpec.selectSet.push_back(&FolderTraversalSelectionSpec);
FolderTraversalSpec.selectSet.push_back(&DataCenterVMTraversalSelectionSpec);
FolderTraversalSpec.selectSet.push_back(&FolderTraversalSelectionSpec);
PropertySpec.type = "Datacenter"; // Change this to Datacenter
PropertySpec.all = &xsd_false; // Change this to false, just get the Datastore property -- will be faster
PropertySpec.pathSet.push_back("name"); // Get the name in case you have multiple datacenters in your inventory
PropertySpec.pathSet.push_back("datastore"); // Get the datastore property
ObjectSpec.obj = ServiceContent->rootFolder;
ObjectSpec.skip = &xsd_true;
ObjectSpec.selectSet.push_back(&FolderTraversalSpec);
ObjectSpec.selectSet.push_back(&DataCenterVMTraversalSpec);
PropertyFilterSpec.propSet.push_back(&PropertySpec);
PropertyFilterSpec.objectSet.push_back(&ObjectSpec);
RetrievePropertiesReq._USCOREthis = ServiceContent->propertyCollector;
RetrievePropertiesReq.specSet.push_back(&PropertyFilterSpec);
You can read up on TraversalSpecs in the VI SDK Programming guide. I sort of take the lazy method of just using a sort of 'generic all' TraversalSpec, but you'll want to review it to understand what inventory objects you can query that way.
What will really start to drive you crazy is when you have to deal with the DynamicProperty data type you get back from your calls. You'll end up with a lot of conditional code using either dynamic_cast or typeid calls. I've been thinking of creating a class, say Entity, that would parse the properties data and build a hash_map similar to how the perl toolkit get_view* and find_entity_view* calls work.
Thank you very much. I'll give this a try and let you know what happens. What I find confusing is that when I access the MOB for my ESX server over the web, I see that the Datacenter object type has a property called 'datastoreFolder' and the value of this property is 'ha-folder-datastore'.
One other thing: I have created 2 VMs on two different ESX servers -- one runs ESX Server 3.5 and the other runs the 4.0 Beta. I can successfully issue a PowerOn command to the ESX 4.0 server using the call: vim->__ns1__PowerOnVM(&powerOnReq, &powerOnRes) (where the powerOnReq object contains a pointer to the VM MOR corresponding to the VM I created). However, when I issue the same command to the ESX 3.5 server, I get the SOAP_FAULT error that I reported previously:
SOAP 1.1 fault: "":ServerFaultCode no subcode
""
Detail:
I am certain I am accessing the VM MOR properly on the ESX 3.5 server because I can print out the correct properties of this machine. I just can't power it on/off, take snapshots, etc. Do you have any idea why the 3.5 server won't allow me to issue these commands? Could it be some kind of permission issue?
ashok
Could be, do you have full admin rights on 3.5?
Hi Ashok,
Let me try to understand what you did with the ESX server, you call the following line of code but supplied a MOR to your host. Am I right?
vim->__ns1__PowerOnVM(&powerOnReq, &powerOnRes)
If so, you for sure got the error message. Basically the PowerOnVM is only applicable for the virtual machine managed object. If you want to power on a host, you want to use... Wait a second, you cannot power on a host using VI SDK at all. But if you want to power it off, then you can use ShutdownHost_Task() method. Check out more @ http://pubs.vmware.com/vi-sdk/visdk250/ReferenceGuide/vim.HostSystem.html
Final note, if you use higher level API like VI Java API, you will not get this problem at all. The compile will enforce the type checking. Find it more at http://vijava.sf.net.
Steve JIN, VMware Engineering
Creator of VMware Infrastructure Java(Jython) API. VI Java API 2.0 --- 15 times faster than AXIS in loading, 4+ faster in deserialization; only 1/4 of the size required by AXIS. More importantly, the freedom to redistribute it with your applications. (Download, Samples, DocWiki, RSS Feed)
Get Connected with Other Developers in the Community?
I didn't get that impression. He stated he had a moref from a VM he created (and used it to populate his PowerOnReq object), then got a fault only when trying to power on the VM on an ESX 3.5 server, his beta 4 worked properly. If it isn't a permission issue Ashok, post up some code. Might be able to see if there is anything off in the call.
I wasn't sure what he did... You are right, sharing more code definitely helps.
Steve JIN, VMware Engineering
Creator of
VMware Infrastructure Java(Jython) API. VI Java API 2.0 --- 15 times faster than AXIS in loading, 4+ faster in deserialization; only 1/4 of the size required by AXIS. More importantly, the freedom to redistribute it with your applications. (
Get Connected with Other Developers in the Community?
Steve and stumpr:
(stumpr: what is your real name by the way?)
I am attaching the small test program that I've been using to power on / power off a specified VM. To recap, I can use this program to manipulate a VM on an ESX 4.0 beta server, but not a VM on an ESX 3.5 server. I am pretty certain that this has nothing to do with permissions on the 3.5 server. The reason for this is that I can powerOn/powerOff a VM on the ESX 3.5 machine using the Java sample program VMpowerOps.java, but I cannot do this with my C++ program. In both programs, I login using the same username ("root") and password.
Here is the command I issue to get the Java program working (note that I use the "--ignorecert" option):
ashok@ashok-ubuntu-vm:~/vi_sdk/SDK/samples/Axis/java$ ./run.sh com.vmware.samples.vm.VMpowerOps --url
https://<ip address>:443/sdk/vimService --username root --password <my password> --vmname ashok_linux_1 --operation poweroff --ignorecert
./run.sh: 48: pushd: not found
RUNNING
Sun Mar 22 00:20:26 PDT 2009 Begin Log.
Started
Powering off virtualmachine 'ashok_linux_1'
Virtual Machine ashok_linux_1 powered off successfuly
Ended VMpowerOps
Why would the powerOn/powerOff operation work correctly from the Java application, but not the C++ app?
It's sort of an issue with the gsoap code generation, but I found an answer after a comparing a few packet captures.
So there are actually two functions created after parsing the VMware vim25 wsdl matching PowerOnVM. One is the
PowerOnVM function you used. However, this will send the method name to the VIM instance as
PowerOnVM which is the VIM service returns as unsupported. This in turn generates the fault code you were seeing.
There is another function,
PowerOnVM_USCORETask. You'll need to use this version (and I suspect you'll need it for every _Task function). This will create the soap envelope with the function name as the VIM service expects.
I'm guessing that Beta 4 either is supports both (or just PowerOnVM).
It's actually an easy fix.
Update your powerVM function to match the following: (I put a "This line has changed" comment at the end of each line I changed)
static void
powerVM(VimBinding* vim, ns1__ServiceContent* serviceContent,
string vm_name, bool powerOn) {
ns1__ManagedObjectReference* vm_mor =
getVMManagedObjectRef(vim, serviceContent, vm_name);
if (powerOn) {
// Power-on the Virtual Machine.
ns1__PowerOnVMRequestType powerOnReq;
_ns1__PowerOnVM_USCORETaskResponse powerOnRes; // This line is changed
powerOnReq._USCOREthis = vm_mor;
if (vim->__ns1__PowerOnVM_USCORETask(&powerOnReq, &powerOnRes) == SOAP_OK) { // This line is changed
cout << "PowerOn of VM " << vm_name << " successful" << endl << endl;
}
else {
cout << "PowerOn of VM " << vm_name << " unsuccessful" << endl << endl;
soap_print_fault(vim->soap,stderr);
soap_done(vim->soap);
soap_end(vim->soap);
exit(1);
}
}
else {
// Power-off the Virtual Machine.
ns1__PowerOffVMRequestType powerOffReq;
_ns1__PowerOffVM_USCORETaskResponse powerOffRes; // This line is changed
powerOffReq._USCOREthis = vm_mor;
if (vim->__ns1__PowerOffVM_USCORETask(&powerOffReq, &powerOffRes) == SOAP_OK) { // This line is changed
cout << "PowerOff of VM " << vm_name << " successful" << endl << endl;
}
else {
cout << "PowerOff of VM " << vm_name << " unsuccessful" << endl << endl;
soap_print_fault(vim->soap,stderr);
soap_done(vim->soap);
soap_end(vim->soap);
exit(1);
}
}
}
I just verified that using the PowerOnVM_USCORETask function on the ESX 3.5 server works fine, thanks for your help! I will let you know if I run into any problems with the datastore object retrieval.
I'm curious as to why gsoap generates both PowerOnVM and PowerOnVM_USCORETask functions. It seems that we should always use the latter function. When would one use the former?
Ashok
Well, both are defined in the WSDL. In fact, the PowerOnVM worked for Beta 4 right?
They may have it in there as a place holder or just not have gotten around to implementing that version on the server side. Don't know. Does the PowerOnVM_Task work on Beta 4 as well? I don't have a b4 system to test against.
Stumpr is right that both methods are there in the WSDL. In the API ref, you only see the *_Task version. Please stick with the *_Task() since the * version may go away.
Steve JIN, VMware Engineering
Creator of
VMware Infrastructure Java(Jython) API. VI Java API 2.0 --- 15 times faster than AXIS in loading, 4+ faster in deserialization; only 1/4 of the size required by AXIS. More importantly, the freedom to redistribute it with your applications. (
Get Connected with Other Developers in the Community?
Hi,
I have followed the same steps listed in this thread to traverse Managed objects to get the list of VMs in my C++ client with gsoap.
Login happened successfully. But RetrieveProperties() is returning zero objects.
(I am using ESX server 3.5.)
The following message appears in /var/log/vmware/hostd.log, whenever I run my client.
2009-05-13 04:24:49.542 'ha-eventmgr' 29846448 info Event 10 : User root@127.0.0.1 logged in
2009-05-13 04:24:49.554 'App' 14834608 error _FetchPropertyPath got unexpected error of type N3Vim5Fault16NotAuthenticated9ExceptionE: vim.fault.NotAuthenticated, for ref=ha-folder-root, path=childEntity
2009-05-13 04:24:49.564 'Vmomi' 3076436896 info Activation
N5Vmomi10ActivationE:0xae06200 : Invoke done
logout on
vim.SessionManager:ha-sessionmgr
2009-05-13 04:24:49.565 'Vmomi' 3076436896 info Throw vim.fault.NotAuthenticated
2009-05-13 04:24:49.565 'Vmomi' 3076436896 info Result:
(vim.fault.NotAuthenticated) {
dynamicType = <unset>,
object = 'vim.SessionManager:ha-sessionmgr',
privilegeId = "System.View",
msg = ""
}
The client code is:
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
#include "visdkH.h"
#include "visdkStub.h"
#include "VimBinding.nsmap"
#include <assert.h>
#include <typeinfo>
using namespace std;
struct soap *soap;
ostringstream server;
void sigpipe_handle(int x) {
cout << "sigpipe: " << x << endl;
}
int getCurrentVMMob(sduvisdk2__ServiceContent *ServiceContent) {
sduvisdk2__TraversalSpec DatacenterToVmFolderTraversalSpec, FolderToChildEntityTraversalSpec;
sduvisdk2__SelectionSpec DatacenterToVmFolderSelectionSpec, FolderToChildEntitySelectionSpec;
sduvisdk2__PropertySpec propertySpec;
sduvisdk2__ObjectSpec objectSpec;
sduvisdk2__PropertyFilterSpec propertyFilterSpec;
sduvisdk2__DynamicProperty dynamicProperty;
sduvisdk2__RetrievePropertiesRequestType retrievePropertiesReq;
_sduvisdk2__RetrievePropertiesResponse retrievePropertiesRes;
sduvisdk2__ManagedObjectReference* vm_mor = NULL;
bool xsd_true = 1;
bool xsd_false = 0;
FolderToChildEntitySelectionSpec.name = new string("DatacenterToVmFolderTraversalSpec");
DatacenterToVmFolderSelectionSpec.name = new string("FolderToChildEntityTraversalSpec");
DatacenterToVmFolderTraversalSpec.name = new string("DatacenterToVmFolderTraversalSpec");
DatacenterToVmFolderTraversalSpec.type = "Datacenter";
DatacenterToVmFolderTraversalSpec.path = "vmFolder";
DatacenterToVmFolderTraversalSpec.skip = &xsd_true;
FolderToChildEntityTraversalSpec.name = new string("FolderToChildEntityTraversalSpec");
FolderToChildEntityTraversalSpec.type = "Folder";
FolderToChildEntityTraversalSpec.path = "childEntity";
FolderToChildEntityTraversalSpec.skip = &xsd_true;
DatacenterToVmFolderTraversalSpec.selectSet.push_back(&FolderToChildEntitySelectionSpec);
FolderToChildEntityTraversalSpec.selectSet.push_back(&DatacenterToVmFolderSelectionSpec);
FolderToChildEntityTraversalSpec.selectSet.push_back(&FolderToChildEntitySelectionSpec);
propertySpec.type = "VirtualMachine";
propertySpec.all = &xsd_false;
propertySpec.pathSet.push_back("name");
objectSpec.obj = ServiceContent->rootFolder;
objectSpec.skip = &xsd_true;
objectSpec.selectSet.push_back(&FolderToChildEntityTraversalSpec);
objectSpec.selectSet.push_back(&DatacenterToVmFolderTraversalSpec);
propertyFilterSpec.propSet.push_back(&propertySpec);
propertyFilterSpec.objectSet.push_back(&objectSpec);
retrievePropertiesReq._USCOREthis = ServiceContent->propertyCollector;
retrievePropertiesReq.specSet.push_back(&propertyFilterSpec);
soap_call___sduvisdk2__RetrieveProperties(soap, server.str().c_str(), "",
&retrievePropertiesReq, &retrievePropertiesRes);
if (soap->error) {
soap_print_fault(soap, stderr);
goto end_of_function;
}
cout << "Retrieved Properties: " << retrievePropertiesRes.returnval.size() << "\n";
for (unsigned int i = 0; i < retrievePropertiesRes.returnval.size(); i++) {
dynamicProperty = *retrievePropertiesRes.returnval->propSet[0];
assert(dynamicProperty.name == "name");
xsd__string* name = (xsd__string*) dynamicProperty.val;
cout << "VM name: " << name->__item << endl;
}
end_of_function:
delete FolderToChildEntitySelectionSpec.name;
delete FolderToChildEntityTraversalSpec.name;
delete DatacenterToVmFolderSelectionSpec.name;
delete DatacenterToVmFolderTraversalSpec.name;
return soap->error;
}
int main(int argc, char *argv[])
{
int ret = 0;
sduvisdk2__RetrieveServiceContentRequestType SvcCont;
_sduvisdk2__RetrieveServiceContentResponse Response;
sduvisdk2__ManagedObjectReference *Mobj;
sduvisdk2__ServiceContent *sc;
sduvisdk2__LoginRequestType login;
_sduvisdk2__LoginResponse loginResponse;
sduvisdk2__LogoutRequestType logout;
_sduvisdk2__LogoutResponse logoutResponse;
sduvisdk2__AboutInfo *about;
sduvisdk2__UserSession *returnval = NULL;
if (argc != 4) {
cout << "Usage: " << argv[0] << " <ESX-server-IP> <user> <passwd>\n";
exit(1);
}
server << "https://" << argv[1] << ":443/sdk";
soap = soap_new();
soap_init(soap);
soap_set_namespaces(soap, namespaces);
Mobj = new sduvisdk2__ManagedObjectReference;
soap_ssl_init();
if (soap_ssl_client_context( soap, SOAP_SSL_NO_AUTHENTICATION, NULL, NULL, NULL, NULL, NULL)) {
std::cout << "SSL:";
soap_print_fault(soap, stderr);
soap_done(soap);
soap_end(soap);
exit(1);
}
Mobj->__item = "ServiceInstance";
Mobj->type = new string("ServiceInstance");
SvcCont._USCOREthis = Mobj;
ret = soap_call___sduvisdk2__RetrieveServiceContent(soap, server.str().c_str(), "", &SvcCont, &Response);
if(SOAP_OK == ret) {
cout << "Retrieve success\n";
} else {
cout << "Soap Errors " << soap->error
<< " " << soap->errnum;
soap_print_fault(soap, stderr);
goto end_of_function;
}
sc = Response.returnval;
if( !sc || !sc->sessionManager ) {
goto end_of_function;
}
about = sc->about;
cout << "---------------------------------------\n"
<< "About Info: \n"
<< "Name :" << about->name << endl
<< "FullName :" << about->fullName << endl
<< "Vendor :" << about->vendor << endl
<< "version :" << about->version << endl
<< "build :" << about->build << endl
<< "osType :" << about->osType << endl
<< "productLineId :" << about->productLineId << endl
<< "apiType :" << about->apiType << endl
<< "apiVersion :" << about->apiVersion << endl
<< "----------------------------------------\n";
login._USCOREthis = sc->sessionManager;
login.userName = argv[2];
login.password = argv[3];
soap_call___sduvisdk2__Login(soap, server.str().c_str(), "", &login, &loginResponse);
if(soap->error != SOAP_OK ) {
soap_print_fault(soap, stderr);
goto end_of_function;
}
returnval = loginResponse.returnval;
cout << "Login success, the details are:\n"
<< "\tUser: " << returnval->userName << endl
<< "\tFull Name: " << returnval->fullName << endl
<< "\tLocale: " << returnval->locale << endl;
ret = getCurrentVMMob(sc);
if (ret != SOAP_OK)
cout << "Failed to get CurrentVMMob\n";
cout << "\nNow Logging out\n";
logout._USCOREthis = sc->sessionManager;
ret = soap_call___sduvisdk2__Logout(soap, server.str().c_str(), "", &logout, &logoutResponse);
if( soap->error != SOAP_OK ) {
soap_print_fault(soap, stderr);
goto end_of_function;
}
cout << "Logout succesful\n";
end_of_function:
soap_done(soap);
soap_end(soap);
}
When I run this code:
$ ./DynamicClient 10.72.197.66 root XXXXX
Retrieve success
About Info:
Name :VMware ESX Server
FullName :VMware ESX Server 3.5.0 build-64607
Vendor :VMware, Inc.
version :3.5.0
build :64607
osType :vmnix-x86
productLineId :esx
apiType :HostAgent
apiVersion :2.5.0
Login success, the details are:
User: root
Full Name: root
Locale: en
Retrieved Properties: 0
Now Logging out
SOAP 1.1 fault: "":ServerFaultCode no subcode
"The session is not authenticated."
Detail:
Why is Logout() call failing. Please let me know if I am doing anything wrong in my client code.
Thanks!
Did you compile all your sources with -DWITH_COOKIES?
Hi stumpr,
Yes. I complied my sources with -DWITH_COOKIES. I am hitting this issue with/without -DWITH_COOKIES.
Thanks!
You have to use WITH_COOKIES, or you will not be authenticated on subsequent calls to the API. Make sure you compiled all components, not just your final executable. I'll take another look at your code and see if anything sticks out.
Hi stumpr,
I tried to generate the stubs once again and compiled the sources with -DWITH_COOKIES. Logout is working fine now.
I see proper messages in /var/log/vmware/hostd.log
2009-05-14 02:21:45.673 'ha-eventmgr' 3076436896 info Event 45 : User root@127.0.0.1 logged in
2009-05-14 02:21:45.697 'ha-eventmgr' 14834608 info Event 46 : User root logged out
When I run the client (attached with this post), no Object Contents are found. Is there anything wrong in my client code (traversing the Mobs)
bash-2.05b$ ./a.out 10.72.197.66 root XXXXX
Retrieve success
About Info:
Name :VMware ESX Server
FullName :VMware ESX Server 3.5.0 build-64607
Vendor :VMware, Inc.
version :3.5.0
build :64607
osType :vmnix-x86
productLineId :esx
apiType :HostAgent
apiVersion :2.5.0
Login success, the details are:
User: root
Full Name: root
Locale: en
Retrieved Properties: 0 <<<<<<<<<<<<<<<<<<<<<<< No VMs found
Now Logging out
Logout succesful
Thanks once again!!
Hi stumpr,
I made an error in following statements:
FolderToChildEntitySelectionSpec.name = new string("DatacenterToVmFolderTraversalSpec");
DatacenterToVmFolderSelectionSpec.name = new string("FolderToChildEntityTraversalSpec");
The client code works fine after correcting them to,
FolderToChildEntitySelectionSpec.name = new string("FolderToChildEntityTraversalSpec");
DatacenterToVmFolderSelectionSpec.name = new string("DatacenterToVmFolderTraversalSpec");
Sorry for troubling you guys.
bash-2.05b$ ./a.out 10.72.197.66 root brooklyn
Retrieve success
About Info:
Name :VMware ESX Server
FullName :VMware ESX Server 3.5.0 build-64607
Vendor :VMware, Inc.
version :3.5.0
build :64607
osType :vmnix-x86
productLineId :esx
apiType :HostAgent
apiVersion :2.5.0
Login success, the details are:
User: root
Full Name: root
Locale: en
Retrieved Properties: 5
VM name: rhel5
VM name: Solaris_VM
VM name: Pattar_rhel4
VM name: winxp
VM name: winserver2k8
Now Logging out
Logout succesful
bash-2.05b$
Thanks a lot!!
I followed the same steps as listed in this post but I am unable to get past the "vim.fault.NotAuthenticated, for ref=ha-folder-root" error. I am working with ESX 4.0 and have no issues accessing it via SDK using the Java samples. For my project I need to build an application in C++ to manage the ESX hosts. I am able to retrieve the ServiceContent and login to the host however my attempts to retrieve the Virtual Machines on the host is failing with following error on the host (hostd-0.log file):
2009-06-2309:12:00.812 F6430B90 info 'ha-eventmgr' Event 123 : User root@127.0.0.1logged in
--2009-06-23 09:12:00.817 F6430B90 error 'App'-- _FetchPropertyPath got unexpected error of type N3Vim5Fault16NotAuthenticated9ExceptionE: vim.fault.NotAuthenticated, for ref=ha-folder-root, path=childEntity
All the application components are built with -DWITH_OPENSSL and -DWITH_COOKIES flags. I have attached the source file (retrieveVMs.cpp) for this program.
Am I doing something wrong in the client code or is this some permissions issue I need to fix on the host? I have another C++ sample program based on the SimpleClient.java sample form SDK and that results in same error.
Thanks!
Probably is from permissions. I tested your code (with some modifications) and it seems is working. Look here http://www.randombugs.com/linux/vmware-webservice-gsoap.html to see a version of your code adapted for VImBinding add with some extra features.
The issue I posted related to authenction was related to cookies. I was building against libgsoapssl++ when I saw this issue. Building with the gsoap source (stdsoap2.cpp) and -DWITH_COOKIES flag resolved the issue.
Your post in randombugs is a good starting point for someone working with VMWare Webservices SDK.
Thanks!
Anyone make any progress on the gsoap with ssl certificate validation on ESX 4.0? I haven't dug in too deep but was playing with it a bit on Friday as time permitted.
Did you see that: http://www.cs.fsu.edu/~engelen/soapdoc2.html#tth_sEc13.1
soap_init(&soap);
soap_ssl_server_context(&soap, SOAP_SSL_DEFAULT, "server.pem", /* keyfile: required when server must authenticate to clients (see SSL docs on how to obtain this file) /
* "password", /* password to read the key file /
* "cacert.pem", /* optional cacert file to store trusted certificates /
* NULL, /* optional capath to directory with trusted certificates /
* "dh512.pem", /* DH file, if NULL use RSA /
* NULL, /* if randfile!=NULL: use a file with random data to seed randomness /
* NULL /* optional server identification to enable SSL session cache (must be a unique name) */
))
I've seen it. Have you run your code against ESX 4.0 servers? If so, post up your gsoap, openssl and OS version please.
Ok, I think I found the issue with the certificates.
The program used to generate the certs (/sbin/generate-certificates) is deleting what I believe is the intermediate certificate. You can see the error when you run openssl verify /etc/vmware/ssl/rui.crt. However, I commented out the rm commands at the end /sbin/generate-certificates script and then combined the files /etc/vmware/ssl/ca.crt and /etc/vmware/ssl/rui.crt into a new file (after deleting my old rui.crt and rui.key files). This is then cleanly verified with openssl verify /etc/vmware/ssl/combined.crt. This certificate will work with VMware ESX 4.0 and gSoap. This is likely to come up with other applications that do not allow you to trust a certificate with an intermediate trust or strictly checks for an intermediary.
I'd chalk this one upto a bug personally. The ca.crt and rui.crt should be concatenated into a single file before cleaning up. This probably won't affect anyone not doing server certificate validation and/or clients that use keychains in the OS (which will probably let you implicitly trust the certificate even without its intermediary).
I just couldn't let this one go, even though I'm not using gsoap as much lately.
This document was generated from the following thread: Problems connecting to VI SDK using C++/gsoap-2.7
InstanceUUID details
I've referred below articles in order to determine how to prevent this issue. According to those articles, the VM property value named "instanceUUID" is the easiest way to uniquely identify a VM in globally. I also checked those instanceUUID values in VM's which are reported duplicate bios.UUID. Even though bios.UUID's duplicated instanceUUID was not duplicated. But I did not find any KB, article or forum related to feeding the data to a CMDB system using instanceUUID values.
Uniquely Identifying Virtual Machines in vSphere and vCloud Part 1: Overview
Uniquely Identifying Virtual Machines in vSphere and vCloud Part 2: Technical
In 2017 he wrote an update to address cross vCenter vMotion:
Uniquely identifying VMs in vSphere Part 3: Enhanced Linked Mode & Cross VC-vMotion
Can anyone please advise us how can we pull those instanceUUID details via vCenter? Is there any other method to extract instanceUUID details from guest OS level? Or any other ways rather than PowerShell.?
VMWare VSphere SDK 6.7 - MOB - VpxSettings and LicenseManager
Hi All,
I am trying to access , ServiceContent = > LicenseManager = > licensedEdition property .
Have generated the files using wsdl available in SDK .
Neither the LicenseMAnager class is present in vim25 folder nor as an entry in DynamicData .java
Also the same with ServiceContent => VpxSetting => setting ["VirtualCenter.FQDN"]
Neither the VPxSetting class is present in vim25 folder nor as an entry in DynamicData .java\
HAve tried accessing the same using OptionValue as well, but not helping.
Any help is highly appreciated.
Thank you.
Looking for sample C++ code to create a vm guest
I'm looking for some sample C++ code that creates a vm guest. Anyone work with gSOAP and C++?
Thanks,
-Ron
CreateVM_Task failure during restore process.
I was able to complete the backup of a VM disks and configuration using a web services C++ wrapper from https://github.com/bfzhao/Native-vShpere. I am in to the restore process now.
During backup, I have stored the whole configuration of the VM (vim.vm.configinfo) as a file. During restore process I read the same to a local data structure(VirtualMachineConfigInfo) and fill VirtualMachineConfigSpec based on the document (https://docs.google.com/viewer?a=v&q=cache:QGSJWZ9-OlIJ:www.vmware.com/support/developer/vddk/vcb_vsphere_backup.pdf+&hl=en&gl=in&pid=bl&srcid=ADGEESiDBbrXuyI_4kXvYgSPdJE8nO5u_PKtxbxLueVl22DaQL0j7EdOuQq4zb_89-_2TVGcRn0FL3L66e0OG9VWjIpKVUgzU-Q4zB3In57It710iy_PKY3UyeDVXspSKB6mdeK0HbGq&sig=AHIEtbSiFf8Yql7XVBrWNyzZMpChaZL9kw) - Creating Virtual Machine section.
When I issue the CreateVM_Task command with the configspec, it fails in the vi client the error shown is "The operation is not supported by the object". Is there a log at the Esx end which can give more details than this to identify where am I going wrong?
Thanks,
./Siva.
config.vpxd.stats.collectPreAggregatedIntervalFactor parameter not present in vcenter 6.5 and 6.7.
Hi,
There is a parameter config.vpxd.stats.collectPreAggregatedIntervalFactor parameter that needs to be set so that collection gets completed within 5 minutes.
This parameter was present for 5.5 and 6.0 but is removed for 6.5 and 6.7.
Because of this for our application collection is not completing in 5 minutes.
Any other variable or parameter is there for this functionality to continue, in case this variable is deprecated.
Thanks
Abhishek P.
Execute SOAP request to Add Virtual Machine to DRS Group
Hi, I've been working with SOAP messages and the vSphere vimService lately. I've ran into a snag. I want to add a virtual machine to an existing DRS group by send a soap call to the API. Here's what I'm trying:
<soap:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<ReconfigureComputeResource_Task xmlns="urn:internalvim25">
<_this xsi:type="ManagedObjectReference" type="ClusterComputeResource">domain-c22</_this>
<spec xsi:type="ClusterConfigSpecEx">
<groupSpec>
<operation>edit</operation>
<info xsi:type="ClusterVmGroup">
<name>migrateVMs</name>
<vm type="VirtualMachine" >vm-2261</vm>
</info>
</groupSpec>
</spec>
<modify>true</modify>
</ReconfigureComputeResource_Task>
</soap:Body>
</soap:Envelope>
Error Message:
Unable to find specified dynamic type "ClusterVmGroup"
Specified dynamic type ClusterVmGroup is not a DataObject type.
If I watch this call happen in Project Onyx using both the VI Client and PowerCLI the exact same call is pretty much being made, without failure. Can anyone provide an explanation on how format my SOAP to make this work? I use onyx for similar operations making SOAP calls and never have problems. I've reviewed the reference API docs, and it looks right...
Kind Regards