Using Code Capture to decipher VMware vCenter APIs

4 minute read
Advanced
1

This post shows how to use the vCenter Server Code Capture utility. Code Capture lets you examine the backend API calls being made when actions are taken in the UI.

Situation

One of my customers was working with the Content Library REST API. He wanted to programmatically upload files to a Content Library. He had gone through the documentation and was able to create a blank item, but could not seem to upload a file into that item.

Code

I ran these REST API commands against my homelab, though it works the same in VMware Cloud on AWS. You can use a tool like Postman to make your life much easier when calling REST APIs directly. However, it is useful to develop the skills necessary to test API calls with curl. Sometimes you need to troubleshoot via command line and you don't have a UI available.

The customer had figured all of the APIs to get an upload started, but the upload never completed. I proceeded to test against my vCenter.

Obtain Session Token

I first need a session token to authenticate calls against my vCenter. The x characters are my redacted password.

> curl -k -i -u administrator@vsphere.local:xxxxxxxxxxxxxx -X POST https://vc02.ad.patrickkremer.com/rest/com/vmware/cis/session

HTTP/1.1 200 OK
date: Thu, 01 Dec 2022 20:46:53 GMT
set-cookie: vmware-api-session-id=4d749bae075630dbbf7c2c831cb36f6f; Path=/rest; Secure; HttpOnly
expires: Thu, 01 Jan 1970 00:00:00 GMT
set-cookie: vmware-api-session-id=4d749bae075630dbbf7c2c831cb36f6f; Path=/api; Secure; HttpOnly
content-type: application/json
x-envoy-upstream-service-time: 131
server: envoy
transfer-encoding: chunked

{"value":"4d749bae075630dbbf7c2c831cb36f6f"}

I save the session ID in a variable for use in subsequent commands.

sessionID="4d749bae075630dbbf7c2c831cb36f6f"

Create item

Create a content library item named TinyLinux

This API call requires a Content Library ID The easiest way to retrieve the Content Library ID is with PowerCLI:

> (get-contentlibrary "HomelabCL").id

f008a41d-ecf1-4728-981e-622e9c7d4ed6

The API call to create the empty content library item, using the Content Library ID:

> curl -k -X POST -H "vmware-api-session-id: $sessionID" -H "Content-Type: application/json" -d '{"library_id":"f008a41d-ecf1-4728-981e-622e9c7d4ed6","name":"TinyLinux"}' https://vc02.ad.patrickkremer.com/api/content/library/item

"2c764989-d0c6-493a-9d04-7461722f46ba"

Get Update Session

To update the empty content library item, I need an Update Session ID. I use the library item ID returned from the previous step.

> curl -k -X POST -H "vmware-api-session-id: $sessionID" -H "Content-Type: application/json" -d '{"library_item_id":"2c764989-d0c6-493a-9d04-7461722f46ba"}' https://vc02.ad.patrickkremer.com/api/content/library/item/update-session

"90962ce7-c82b-4d1f-8392-e2683607821d:9db92255-bc00-4e91-9777-0e37928c5771"

Configure Upload

To configure the upload, I need to point the upload session to a file. I placed my ISO file on my webserver to make it publicly accessible, then run the API call to ingest it into the content library. I use the update session returned from the previous step.

> curl -k -X POST -H "vmware-api-session-id: $sessionID" -H "Content-Type: application/json" -d '{"name":"TinyCore-current.iso","source_endpoint":{"uri":"http://www.patrickkremer.com/binuploads/TinyCore-current.iso"},"source_type":"PULL"}' https://vc02.ad.patrickkremer.com/api/content/library/item/update-session/90962ce7-c82b-4d1f-8392-e2683607821d:9db92255-bc00-4e91-9777-0e37928c5771/file

{"bytes_transferred":0,"source_endpoint":{"uri":"http://www.patrickkremer.com/binuploads/TinyCore-current.iso"},"name":"TinyCore-current.iso","source_type":"PULL","keep_in_storage":true,"status":"WAITING_FOR_TRANSFER"}

At this point, the upload is stuck at 1%. This is the same behavior the customer was seeing. Pending Upload

Send Complete Action

The final key to this puzzle is to send the Complete action, which triggers the upload to begin. The file is now successfully uploaded.

 > curl -k -X POST -H "vmware-api-session-id: $sessionID" -H "Content-Type: application/json" https://vc02.ad.patrickkremer.com/api/content/library/item/update-session/90962ce7-c82b-4d1f-8392-e2683607821d:9db92255-bc00-4e91-9777-0e37928c5771?action=complete

Completed Upload

Code Capture

I had never worked with the Content Library API before this customer needed help. How did I figure it out the call that I needed? I used Code Capture in the vCenter UI.

I start Code Capture by clicking the record button. Enabling Code Capture

I uploaded my iso file through the UI, then clicked Stop

End Code Capture

All of the individual calls that the vCenter UI made are visible in the capture window.

#----------------- Start of code capture -----------------

#---------------probe---------------
$source_endpoint = @{}
$source_endpoint.uri = 'http://www.patrickkremer.com/binuploads/TinyCore-current.iso'
$_this = Get-CisService 'com.vmware.content.library.item.updatesession.file'
$_this.probe($source_endpoint)

#---------------create---------------
$client_token = 'c390c018-cc0a-445c-a08b-5212313845d2'
$create_spec = @{}
$create_spec.library_id = 'f008a41d-ecf1-4728-981e-622e9c7d4ed6'
$create_spec.name = 'TinyLinux'
$create_spec.description = ''
$create_spec.type = 'iso'
$_this = Get-CisService 'com.vmware.content.library.item'
$_this.create($client_token, $create_spec)

#---------------create---------------
$client_token = '13340e25-386b-4821-b387-6aadccf354c7'
$create_spec = @{}
$create_spec.library_item_id = 'f1146f76-a443-4f23-8669-e9d6626119b6'
$_this = Get-CisService 'com.vmware.content.library.item.update_session'
$_this.create($client_token, $create_spec)

#---------------add---------------
$update_session_id = 'd0bc606c-ec7d-482b-af85-73334484da62:9db92255-bc00-4e91-9777-0e37928c5771'
$file_spec = @{}
$file_spec.source_endpoint = @{}
$file_spec.source_endpoint.ssl_certificate_thumbprint = ''
$file_spec.source_endpoint.uri = 'http://www.patrickkremer.com/binuploads/TinyCore-current.iso'
$file_spec.name = 'TinyCore-current.iso'
$file_spec.source_type = 'PULL'
$_this = Get-CisService 'com.vmware.content.library.item.updatesession.file'
$_this.add($update_session_id, $file_spec)

#---------------get---------------
$update_session_id = 'd0bc606c-ec7d-482b-af85-73334484da62:9db92255-bc00-4e91-9777-0e37928c5771'
$_this = Get-CisService 'com.vmware.content.library.item.update_session'
$_this.get($update_session_id)

#---------------get---------------
$update_session_id = 'd0bc606c-ec7d-482b-af85-73334484da62:9db92255-bc00-4e91-9777-0e37928c5771'
$_this = Get-CisService 'com.vmware.content.library.item.update_session'
$_this.get($update_session_id)

#---------------complete---------------
$update_session_id = 'd0bc606c-ec7d-482b-af85-73334484da62:9db92255-bc00-4e91-9777-0e37928c5771'
$_this = Get-CisService 'com.vmware.content.library.item.update_session'
$_this.complete($update_session_id)


#----------------- End of code capture -----------------

The final call caught my attention - it shows a call to complete. I was then able to search the API documentation for complete and found the correct API call to finalize the upload. Code Capture let me pinpoint the required API call within a few minutes. Now you have another tool in your arsenal to make your troubleshooting efforts more efficient.

profile picture
AWS
EXPERT
published 2 months ago157 views