VMware {code} Community
dave012345
Enthusiast
Enthusiast
Jump to solution

Writing SOAP calls manually

I need to find a good reference or tool to help write SOAP calls. I am using SOAPUI to talk to vimService.wsdl. An example of a simple task that I'm trying to do:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:vim25">

   <soapenv:Header/>

   <soapenv:Body>

      <urn:CreateVirtualDisk_Task>

         <urn:_this type="?">?</urn:_this>

         <urn:name>?</urn:name>

         <!--Optional:-->

         <urn:datacenter type="?">?</urn:datacenter>

         <urn:spec>

            <!--Optional:-->

            <urn:dynamicType>?</urn:dynamicType>

            <!--Zero or more repetitions:-->

            <urn:dynamicProperty>

               <urn:name>?</urn:name>

               <urn:val>?</urn:val>

            </urn:dynamicProperty>

            <urn:diskType>?</urn:diskType>

            <urn:adapterType>?</urn:adapterType>

         </urn:spec>

      </urn:CreateVirtualDisk_Task>

   </soapenv:Body>

</soapenv:Envelope>

I was using the following as a reference, but it seems more geared towards folks using an IDE/SDK. http://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.VirtualDiskManager.html#...

(there is a reason I'm not using the SDK, we have an extant platform that can make HTTP requests and it is not possible to modify that platform to include vSphere SDK)

My problems:

What do I put in _this type? The above reference documentation is not helpful for writing SOAP calls.

Is there a tool or utility or reference I can use to figure out what needs to go into these SOAP calls?

0 Kudos
1 Solution

Accepted Solutions
stumpr
Virtuoso
Virtuoso
Jump to solution

Yup.  In Perl, you can use --verbose on the command line of any script and it will spit out out the raw XML.  I'm not sure if Python has a debug option that is similar or not.  You could use that to capture some your SOAP "templates" and just do the appropriate search and replace where necessary.  Example:

REQUEST: $VAR1 = '<?xml version="1.0" encoding="UTF-8"?>

   <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"

                     xmlns:xsd="http://www.w3.org/2001/XMLSchema"

                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

   <soapenv:Body>

<ReconfigVM_Task xmlns="urn:vim25"><_this type="VirtualMachine">vm-100</_this>

<spec><deviceChange><operation>edit</operation><device xsi:type="VirtualDisk"><key>2000</key><deviceInfo><label>Hard disk 1</label><summary>524,288 KB</summary></deviceInfo><backing xsi:type="VirtualDiskFlatVer2BackingInfo"><fileName>[GlobalDS_0] DC0_C0_RP6_VM7/DC0_C0_RP6_VM7.vmdk</fileName><datastore type="Datastore">datastore-30</datastore>

<diskMode>persistent</diskMode><split>0</split><writeThrough>0</writeThrough><thinProvisioned>0</thinProvisioned><uuid>520ee694-2b4b-6f6e-9c13-f89af8ac8554</uuid></backing><controllerKey>1000</controllerKey><unitNumber>0</unitNumber><capacityInKB>524288</capacityInKB><shares><shares>3670072</shares><level>low</level></shares><storageIOAllocation><limit>10</limit></storageIOAllocation></device></deviceChange></spec></ReconfigVM_Task></soapenv:Body></soapenv:Envelope>

';

RESPONSE: $VAR1 = '<?xml version="1.0" encoding="UTF-8"?>

<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"

xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<soapenv:Body>

<ReconfigVM_TaskResponse xmlns="urn:vim25"><returnval type="Task">task-1223</returnval></ReconfigVM_TaskResponse>

</soapenv:Body>

</soapenv:Envelope>';

It's a bit painful when you start dealing with objects from several sources and building envelopes by hand can get brutal when you move into nested objects in the XML.  But if you got a small set of operations and objects to deal with, should work with some regex.  There are a few other places it may get tricky, for example, sometimes you have inherited objects of a specific type and they get serialized by specifying the type depending on the object.  In that case you'll need to preserve the type and value when passing those objects around.

An example is the VirtualDevice here:

<device xsi:type="VirtualDisk">...</device>

In this case it's a VirtualDisk, but it could also be a VirtualEthernetCard (VirtualE1000 is a child of VirtualEthernetCard), VirtualFloppy, VirtualCdrom, etc.

If you have a Python adapter, then look at PyVmomi.  It will probably save you a lot of pain and misery long term Smiley Happy  Project Onyx used to support SOAP outputs as well, but not sure if that project is maintained, supported or even updated for later API versions.

Reuben Stump | http://www.virtuin.com | @ReubenStump

View solution in original post

0 Kudos
7 Replies
stumpr
Virtuoso
Virtuoso
Jump to solution

You may be in for a world of pain Smiley Happy  Some of the calls are pretty deeply nested.

But the first problem will be the ManagedObjectReference (_this) in your example.

That is in the format of:

<_this type="vim25:Datacenter">datacenter-123</_this>


You will be slinging ManagedObjectReferences a lot.  Same context:

<datacenter type="vim25:Datacenter">datacenter-123</_datacenter>

MoRef values are usually provided by other queries against the API.

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
dave012345
Enthusiast
Enthusiast
Jump to solution

Thanks!

I have done a lot of the work through PowerCLI which is not ideal as a middleware agent, hence transferring everything to use the API. So I'm quite familiar with using morefs, it's just that the SDK documentation really isn't for what I am trying to do Smiley Sad

So how did you get from VirtualDiskManager to vim25:Datacenter? What reference or tools do you use? I don't want to have to post a thread to figure out each HTTP request I come across!

0 Kudos
stumpr
Virtuoso
Virtuoso
Jump to solution

Under the covers, all the SDKs (including PowerCLI) use the same calls, just wrap them for simplicity.

You'll have to parse your SOAP responses.  You can get your target MoRefs from a lot of sources - RetrievePropertiesEx, SearchIndex.FindBy* calls, etc.  Like I said, raw SOAP parsing against the vSphere API is painful.  I just converted most of it into JSON for a simple Perl module (speed and memory optimization) and it was 2801 entity types and 615 operations Smiley Sad

You definitely can't integrate say PyVmomi or VIPerl into the toolset?

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
dave012345
Enthusiast
Enthusiast
Jump to solution

No, unfortunately I cannot get access to the inner workings of the platform I'm using, but I have put in a request for enhancement for our devs to add a vSphere API plugin.

Is it possible to use those tools you referenced (PyVmomi or VIPerl) to generate SOAP calls? It would be worth it to me even if I have to setup the SDK or some other tools just to generate the calls I need for testing/experimentation purposes.

EDIT: I might have lied, we may have a Python adapter available. I will update soon.

0 Kudos
stumpr
Virtuoso
Virtuoso
Jump to solution

Yup.  In Perl, you can use --verbose on the command line of any script and it will spit out out the raw XML.  I'm not sure if Python has a debug option that is similar or not.  You could use that to capture some your SOAP "templates" and just do the appropriate search and replace where necessary.  Example:

REQUEST: $VAR1 = '<?xml version="1.0" encoding="UTF-8"?>

   <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"

                     xmlns:xsd="http://www.w3.org/2001/XMLSchema"

                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

   <soapenv:Body>

<ReconfigVM_Task xmlns="urn:vim25"><_this type="VirtualMachine">vm-100</_this>

<spec><deviceChange><operation>edit</operation><device xsi:type="VirtualDisk"><key>2000</key><deviceInfo><label>Hard disk 1</label><summary>524,288 KB</summary></deviceInfo><backing xsi:type="VirtualDiskFlatVer2BackingInfo"><fileName>[GlobalDS_0] DC0_C0_RP6_VM7/DC0_C0_RP6_VM7.vmdk</fileName><datastore type="Datastore">datastore-30</datastore>

<diskMode>persistent</diskMode><split>0</split><writeThrough>0</writeThrough><thinProvisioned>0</thinProvisioned><uuid>520ee694-2b4b-6f6e-9c13-f89af8ac8554</uuid></backing><controllerKey>1000</controllerKey><unitNumber>0</unitNumber><capacityInKB>524288</capacityInKB><shares><shares>3670072</shares><level>low</level></shares><storageIOAllocation><limit>10</limit></storageIOAllocation></device></deviceChange></spec></ReconfigVM_Task></soapenv:Body></soapenv:Envelope>

';

RESPONSE: $VAR1 = '<?xml version="1.0" encoding="UTF-8"?>

<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"

xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<soapenv:Body>

<ReconfigVM_TaskResponse xmlns="urn:vim25"><returnval type="Task">task-1223</returnval></ReconfigVM_TaskResponse>

</soapenv:Body>

</soapenv:Envelope>';

It's a bit painful when you start dealing with objects from several sources and building envelopes by hand can get brutal when you move into nested objects in the XML.  But if you got a small set of operations and objects to deal with, should work with some regex.  There are a few other places it may get tricky, for example, sometimes you have inherited objects of a specific type and they get serialized by specifying the type depending on the object.  In that case you'll need to preserve the type and value when passing those objects around.

An example is the VirtualDevice here:

<device xsi:type="VirtualDisk">...</device>

In this case it's a VirtualDisk, but it could also be a VirtualEthernetCard (VirtualE1000 is a child of VirtualEthernetCard), VirtualFloppy, VirtualCdrom, etc.

If you have a Python adapter, then look at PyVmomi.  It will probably save you a lot of pain and misery long term Smiley Happy  Project Onyx used to support SOAP outputs as well, but not sure if that project is maintained, supported or even updated for later API versions.

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
dave012345
Enthusiast
Enthusiast
Jump to solution

Looks like Project Onyx is my ticket. The latest version allows you pipe PowerCLI (which is what all my current automation uses) into Onyx which then spits out the raw SOAP calls. That's pretty much perfect. I can run some of my scripts and then just copy/paste the SOAP calls with the variables inserted. Thanks again, Project Onyx is perfect for my needs. VMware Project Onyx

It doesn't seem to be compatible with PowerCLI 5.8 but hopefully 5.5 works.

stumpr
Virtuoso
Virtuoso
Jump to solution

Yeah, haven't used Onyx in a while, but it was really useful.  Glad that worked.  You were going to start throwing things trying to hand build the SOAP calls Smiley Wink

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