VMware {code} Community
Tyknee
Contributor
Contributor

PHP - vSphere WSDL Primer

I'm not sure if this is the "correct" place for this, but after spending HOURS of searching and many, many curse words, I wanted to share a quick little guide to using PHP to interface with the vSphere WSDL. I'm doing this because there is a lot of information spread out all over the Internet, however no one source ever really brought it all together. That is my goal here in this post. Note that I don't claim any of this to be really my own work, but rather my collection of other's work put together in one place. I would link to all the places I found this info, but honestly it came from so many places and was crosslinked to others that I can't even remember where I found most of this stuff. I've also interspersed this with my ramblings and thoughts on the whole process.

Please note I am NOT a developer. I'm just an admin trying to write a few scripts that I can use on some webpages to make my life (and some of my fellow admins lives) easiser. So I don't use a lot of functions and constants, I'll just write a new script if I need to do something else. (I think one of my major stumbling blocks was that the documentation was written for people creating large complicated applications, but that's just IMHO.)

Step 1 - What you'll need
-- You'll need PHP installed (Duh). I'm using version 5.3.3 but that shouldn't matter all that much. Newer versions may change some things slightly. I'm also using the built in soap client.
--You'll need vCenter (double Duh). I've tested this on 5.0 and 5.1. I'm sure there are differences, but I don't know what they are (and I don't care as long as my stuff works).
--You'll need your vcenter name or IP address. and you'll want to verify that the WSDL is at the correct location. You should be able to browse to your WSDL by going to "https://vcenter/sdk/vimService.wsdl". If you can't find it there, you'll need to figure out where it is.
--You'll also need to have a username and password to log into vCenter with. You should be able to use whatever credentials you log into the (Web or Destop) vSphere client. You should also probably know a little something about vSphere and stuff like "what a datastore is" vs "what a VM is".
--Finally you'll want to access your "MOB" at http://vcenter/mob. It will help navigating VMware's object structure.

Step 2 - Create SOAP client object
This probably shouldn't be your first ever PHP and SOAP script you attempt. So I assume you already know how to request a stock quote from webservicex.net or something. That being said, here's the setup:

$client = new SoapClient(
https://vcenter/sdk/vimService.wsdl,
     array (
          "trace" => 1,
          https://vcenter/sdk/,
          )
);

Here we create a new soapclient and point it to our Vcenter WSDL. Note that you don't provide login information here (that stumped me for a good little while). Replace the "vcenter" with your Vcenter name or IP. The may be more "options" you want to play with for creating the soap client, you can add those to the array.


Step 3 - Let's start to do something that might seem productive
For whatever reason, the first thing you'll have to do is invoke the "ServiceInstance". I have no idea why, but you do. Here is how to do that:

$soapmessage["_this"] = new Soapvar ("ServiceInstance", XSD_STRING, "ServiceInstance");
$result = $client->RetrieveServiceContent($soapmessage);
$serviceContent = $result->returnval;

Here we create a "SoapVar" object, and give it some data. For some reason, I wasn't able to use a standard Object, not sure why. (Maybe I'm just not that smart? Standard objects always worked for me with other WSDLs, but w/e). We then invoke the "RetrieveServiceContent" method to create a ServiceInstance, which returns a bunch of data to the variable $result. We then load that information into a variable called "serviceContent". (You'll find that some of my variable names make no sense. That's because I was somewhat clueless as to what this was all doing when I wrote it. Feel free to change it to something else. Like I care what you call your own variables...)

Step 4 - Log in so it knows who we are
So if we want to do something productive, we're going to have to tell it who we are. The $result variable has some info we need, specifically the "sessionManager" object. SessionManager has a method called "Login", which sounds like what we're trying to do.

$soapmessage2["_this"] = $serviceContent->sessionManager;
$soapmessage2["userName"]='username';
$soapmessage2["password"]='password';
$result = $client->Login($soapmessage2);
$usersession = $result->returnval;

The "_this" refers to which object we're referencing (This is the session manager object that we got from the service instance above) Username and password are (TRIPLE DUH) your username and password. You'll probably want to change that to your actual username and password, unless your username and password really are "username" and "password". (If they are, please send me your IP address in a PM. Also, please include your ATM pin, mother's maiden name, and SSN.)

We then invoke the Login method, and get a result. I loaded that result into another variable, not sure why.

Step 5 - Um, can we actually do something now?
Here is where EVERY OTHER LINK I EVER SAW really failed epically. Most posts have you log out here. WHY WOULD I LOG OUT? WE DIDN'T DO ANYTHING YET!

Normally at this point you're probably going to need to get a "Managed Object ID", aka MOID. Think of the MOID as a name that never changes. You might have a VM called "Bob", but it's MOID is something like "vm-1234". If you rename your VM from "Bob" to "Weave", the MOID stays the same. They seem to follow a standard of some sort of identifier followed by a number. So your datacenter may be something like "datacenter-4893" and a datastore might be "datastore-6969". Folders are called "antifungalcream-123..." okay I'm kidding, they look something like "group-1231".

The reason you're going to need your MOID is because that's what you reference when you call your methods. So if you want to rename something, you'll need to tell it what you're renaming. The method for renaming a folder/host/VM is the same method, you just reference a different object.

I got my MOID by using the "FindByDNSName" method, under "SearchIndex". SearchIndex (and everything else???) is under the the "serviceContent".
Here is the code for that:

$soapmessage3["_this"] = $serviceContent->searchIndex;
$soapmessage3["dnsName"]='servername.domain.org';
$soapmessage3["vmSearch"]='true';
$result = $client->FindByDnsName($soapmessage3);
$vmentity = $result->returnval;

(Why did I have to tell it "Vmsearch = true". Did they think I was calling a search method but didn't want to search???)

The return is going to have your MOID

Step 6 Okay NOW we REALLY DO SOMETHING!
After you have your MOID, you just have to call a method that is valid for it. So if you're using a VM, your methods are "Rename_Task, PowerOnVM_Task, etc. For testing purposes, I was using "QueryFaultToleranceCompatibility" method. It just returns some data (no idea what this data really means), but it will tell you if your MOID is correct.

$soapmessage4["_this"] = $vmentity;
$result = $client->QueryFaultToleranceCompatibility($soapmessage4);

That's it! HOORAY WE DID SOMETHING! After four soap calls, we've actually done something that might be considered productive.

Step 7 NOW WE CAN LOG OUT

$soaplogout["_this"] = $serviceContent->sessionManager;
$result = $client->Logout($soaplogout);

Not much to figure out here.

Step 8 PROFIT!
The "ace trick" is finding your MOID. You'll need to figure out which search or method is best for you to use. This is where your "MOB" (referenced above in step 1) will be helpful, as you can browse and find methods and which MOIBs they can be called on. You might want to start in the "rootFolder". In the MOB click on "RetrieveServiceContent", then click "invoke method", then click "Group-d1" (apparently this is the default root folder, and it's always called that). From here you should see your data centers, you can click on them and browse folders/datastores/etc. The MOIDs are referenced as well as the properties and methods.

Final thoughts : This is by far the most complicated and obtuse WSDL I've ever had to work with. I thought I was getting good at it until I saw this one. Normally I can just read the WSDL and figure it out from there, but there's no way any human could do that with this one IMO. It also wasn't helpful to read people's responses like "You should use Java/Perl". Um, if I wanted to write Java, I'd write Java. Isn't the whole point of a WSDL to be language independant? Why should I go learn a whole new programming language?

Also, 4 soap calls to rename a VM? Does that seem reasonable? Usually I can do stuff like this in 1 or 2.

Message was edited by: Tyknee - Of course I had to go into the HTML and edit this to get it to look right. Board software was probably written by the same guy who wrote the WSDL...

Reply
0 Kudos
3 Replies
stumpr
Virtuoso
Virtuoso

Nice work, it's great to see this data pulled together in a nice write-up!

I think the usual problem is deserializing or serializing more complex objects, however.  For example, how about ReconfigureTask() where you add a new NIC to a VM?  Without the object types, hand crafting the Soap objects can get pretty complex.  Particularly if they don't follow 100% standard (which some due, such as ManagedObjectReference).

Reuben Stump | http://www.virtuin.com | @ReubenStump
Reply
0 Kudos
umaparvathy
Enthusiast
Enthusiast

HI ,

Could you please show sample for InitiateFileTransferToGuest or AcuquireCredentailsInGuest method via soap client. I'm stuck at  passing the auth in InitiateFileTransfer it says dynamicType and dynamicProperty is unset.

Reply
0 Kudos
Stacey1C
Contributor
Contributor

Amazing work. Thanks for sharing this data. Its really helpful!

Reply
0 Kudos