VMware Communities > VMware Developer > Forums > vSphere™ Web Services SDK > Discussions

This Question is Answered

1 "correct" answer available (10 pts) 2 "helpful" answers available (6 pts)
5 Replies Last post: Aug 13, 2009 6:26 AM by bob54321
Reply

403 forbidden status code when trying to PUT vmdks

Jul 4, 2009 8:51 AM

Click to view bob54321's profile Lurker bob54321 3 posts since
Jul 4, 2009
Hi,

I'm trying to upload a VM in an ovf+vmdk file format via the webservices SDK to a vcenter/esx and am running into some issues. Heres a brief description of what is being done:

  • use the com.vmware.vim25.OvfCreateImportSpecParams method with a VM name, the ESX info, and network mappings
  • the come.vmwarevim25.OvfCreateImportSpecResult that comes back looks ok (no warnings), except all the OvfFileItems have create = false (possibly a sign of something wrong right here)
  • we then go on to create a HttpNfcLease via the importVApp command, and wait on it properly as per the api programming guide - i believe all this works fine
  • when we iterate over the HttpNfcLeaseDeviceUrl.getUrls() and attempt to PUT the content to them, we get the 403's.

In the vpx.log file on the esx's we get the following errors when we try to do this:

2009-07-03 15:22:17.751 0x16eb1b90 info 'HttpNfcServer' DiskUploadWorker PUT request /vmfs/volumes/4a23c7fd-05389109-b84c-0022192b1768/bob17/bob17.vmdk (/nfc/13794651-5df7-49ae-ab1f-e96dc543cdeb/disk-0.vmdk)
2009-07-03 15:22:17.752 0x16eb1b90 info 'HttpNfcServer' DiskUploadWorker File exists, overwrite not allowed: /vmfs/volumes/4a23c7fd-05389109-b84c-0022192b1768/bob17/bob17.vmdk

So obviously something in the import spec or ovf needs to convince ESX that WE actually want to overwrite these files, but i can't figure out what that is. If i pause my code right before the upload, delete all the vmdk files from the ESX, the PUT will succeed, and the VM upload will be successful.

Any tips or points would be appreciated - thanks!

Bob
Reply Re: 403 forbidden status code when trying to PUT vmdks Jul 4, 2009 10:13 AM
Click to view lamw's profile Champion lamw 2,748 posts since
Nov 27, 2007
You may want to provide the snippet of code you're using, also it sounds like the issue is you're importing a VM that already exists, specifically duplicated the VMDK(s). Have you tried to provide a different name and see if you get the same error?

=========================================================================
William Lam
VMware vExpert 2009
VMware ESX/ESXi scripts and resources at: http://engineering.ucsb.edu/~duonglt/vmware/
vGhetto Script Repository
VMware Code Central - Scripts/Sample code for Developers and Administrators
http://twitter.com/lamw

http://engineering.ucsb.edu/~duonglt/vmware/vexpert_silver_icon.jpg

If you find this information useful, please award points for "correct" or "helpful".

Reply Re: 403 forbidden status code when trying to PUT vmdks Jul 4, 2009 11:44 AM
in response to: lamw
Click to view bob54321's profile Lurker bob54321 3 posts since
Jul 4, 2009
Thanks for the reply!

The VM name that we use is definitely NOT in use. The log in my first message used VM name = bob17 as the name of the vm, and i keep incrementing it for every attempt.

The code is quite verbose and crude with a lot of our own internal structures, but here are two snippets - the first is of getting the HttpNfcLease:

public static HttpNfcLease getHttpNfcLease(String ovfDescriptor, String biosUuid, String applianceName, String datastoreName, String dcName, VirtualConnection vConnection) throws ... {
try {

com.vmware.apputils.vim25.ServiceConnection S1 = vConnection.getConnection();
VimPortType service = S1.getService();
ServiceContent content = S1.getServiceContent();
ManagedObjectReference datacenter = getDatacenter(vConnection.getServiceUtil(), dcName);
ManagedObjectReference esxMor = getHost(biosUuid, vConnection);
ManagedObjectReference resourcePool = getResourcePool(vConnection.getServiceUtil(), esxMor, datacenter);
ManagedObjectReference folder = vConnection.getServiceUtil().getMoRefProp(datacenter, "vmFolder");
ManagedObjectReference datastore = getDatastore(vConnection.getServiceUtil(), esxMor, datastoreName);
com.vmware.vim25.OvfNetworkMapping[] networkMappings = new com.vmware.vim25.OvfNetworkMapping[2];
ManagedObjectReference] networks = (ManagedObjectReference[)vConnection.getServiceUtil().getDynamicProperty(esxMor, "network");
/* snip snip - setup networkMappings */

com.vmware.vim25.OvfCreateImportSpecParams cisp = new com.vmware.vim25.OvfCreateImportSpecParams( null,
null,
"",
"",
null,
applianceName,
esxMor,
networkMappings,
null,
null,
null);
com.vmware.vim25.OvfCreateImportSpecResult cisr = service.createImportSpec(content.getOvfManager(), ovfDescriptor, resourcePool, datastore, cisp);
com.vmware.vim25.OvfFileItem[] fileItems = cisr.getFileItem(); // ******** all the files have create=false
com.vmware.vim25.LocalizedMethodFault[] faults = cisr.getWarning(); // ******** this is empty
return new HttpNfcLease(service.importVApp(resourcePool, cisr.getImportSpec(), folder, esxMor));
} catch (Exception e) {
throw new /* snip snip */
}
}

And then here is the PUT code:


httpLease = VsphereToolkit.getHttpNfcLease(ovf, uuid, applianceName, datastoreName, dcName, c);

do {
doSleep(1000);
} while (httpLease.getLeaseState(c).equals(VsphereToolkit.HttpNfcLease.LEASE_STATE_INITIALIZING));

String state = httpLease.getLeaseState(c);
if(state.equals(VsphereToolkit.HttpNfcLease.LEASE_STATE_READY)) {
List<String> uploadUrls = httpLease.getUploadUrls(c);
int totalBytes = 0;
int bytesDownloaded = 0;
for(File file : vmdkFiles) {
totalBytes += file.length();
}
for(int x=0;x<uploadUrls.size();x++) {
String url = uploadUrls.get(x);
File file = vmdkFiles[x];
System.out.println("Url " + x + ": " + url);
HttpsURLConnection urlConnection = (HttpsURLConnection)new URL(url).openConnection();
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
urlConnection.setHostnameVerifier(hv);
urlConnection.setSSLSocketFactory(/* our default socket factory */);
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("PUT");
urlConnection.setRequestProperty("Content-Length", String.valueOf(file.length()));
urlConnection.setFixedLengthStreamingMode((int)file.length());
urlConnection.connect();

/* if we check the status code here or afterwards, it is 403 */
// int resultCode = urlConnection.getResponseCode();

OutputStream os = urlConnection.getOutputStream();
FileInputStream fis = new FileInputStream(file);
byte b[] = new byte1024 * 4;
int count = 0;
int lastPercent = 0;
while ((count = fis.read(b)) != -1) {
bytesDownloaded += count;

/* *************eventually fails here after the first few writes */
os.write(b, 0, count);

os.flush();
}
fis.close();
os.close();
InputStream is = urlConnection.getInputStream();

Reply Re: 403 forbidden status code when trying to PUT vmdks Aug 12, 2009 5:36 PM
in response to: bob54321
Click to view sthakkar's profile Novice sthakkar 9 posts since
Aug 7, 2009
Hi there,

I was doing a similar importVapp operation in java as well. How did you go about creating the import spec?

I have been trying to create mine by reading in the ovf file into a string buffer and then subsequently calling:

OvfCreateImportSpecParams cisp = new OvfCreateImportSpecParams();
cisp.setNetworkMapping(null);
cisp.setPropertyMapping(null);
cisp.setIpProtocol("");
cisp.setIpAllocationPolicy("");
cisp.setHostSystem(host.getMOR());
cisp.setEntityName("autovm");
cisp.setLocale("");
OvfCreateImportSpecResult is = om.createImportSpec(strContent, rp, dc.getDatastores()[1], cisp); //where strContent is the ovf data
HttpNfcLease nfcLease = rp.importVApp(is.getImportSpec(), dcVMfolder, host);

I was trying to create the import spec to pass to importVapp but was getting the following error. Did you encounter anything similar?

java.rmi.RemoteException: VI SDK invoke exception:org.dom4j.DocumentException: null Nested exception: null
at com.vmware.vim25.ws.WSClient.invoke(WSClient.java:176)
at com.vmware.vim25.ws.WSClient.invoke(WSClient.java:119)
at com.vmware.vim25.ws.VimStub.createImportSpec(VimStub.java:1097)
at com.vmware.vim25.mo.OvfManager.createImportSpec(OvfManager.java:69)
<snip>

I've tried escaping the xml (which didn't make much sense) but I read about the error in another forum. As expected, it didn't affect much. I've also double checked my ovf to verify its xml validity.

Does anyone have any insight into what could be causing this?

Thanks in advance!
Reply Re: 403 forbidden status code when trying to PUT vmdks Aug 13, 2009 1:40 AM
Click to view tos2k's profile Expert tos2k 304 posts since
May 11, 2007
Two questions, no answers :-)

1) Why dont you delete all the files from within your app, if things work perfectly when deleting the files manually?
2) Do you run your app against vCenter? If so, try to run it against ESX directly, and if there is data, run it throught that ESX that "owns" the data.

Tos2k
Reply Re: 403 forbidden status code when trying to PUT vmdks Aug 13, 2009 6:26 AM
in response to: tos2k
Click to view bob54321's profile Lurker bob54321 3 posts since
Jul 4, 2009

Hi,

I should note we did solve our issue - we were led astray by the documentation saying that PUT was required. We changed to a POST and now all is well, it can overwrite what is there, and life is good.

Thanks!

Bob

Actions