If you are using vCloud Director in your environment and if you have ever tried doing a Storage vMotion of a VM from vSphere directly, you will notice a warning saying that its not recommended to modify the entity since its managed by VCD.

sv-1

This is because of the the fact that with VCD, the management layer lies with itself and not with vSphere. All changes to the entities should be made via vCD and not vSphere.

Although doing a storage migration will not break anything but as a best practice we should avoid that.

So what to do if one of your backend LUN is full and you need to evacuate that by migrating some vm’s to another datastore which have enough free space. The answer is by using “Rest API”.

About the VMware vCloud API

The VMware vCloud API provides support for developers who are building interactive clients of VMware vCloud Director using a RESTful application development style. vCloud API clients communicate with servers over HTTP, exchanging representations of vCloud objects. These representations take the form of XML elements.

You use HTTP GET requests to retrieve the current representation of an object, HTTP POST and PUT requests to create or modify an object, and HTTP DELETE requests to delete an object.

To know more about vCD Rest API please read vCloud API Programming Guide.

Which tools to use?

There are various tools available on internet which can be used to interact with vCD Rest API. Most common tools include:

1: Postman Rest Client (chrome extension) which can be added to chrome from webstore.

2: Rest Client for firefox. It can be downloaded from here

3: Using curl which can be downloaded from here

Since I am fan of command line, in my lab I have installed curl on one of my linux box.

Once you have downloaded and installed curl, you can follow below steps to storage migrate your VM.

Note: I am using API calls against my environment which is hosted in vCloud Air

 

1: Generate session key 

The first thing to use API is to generate an Auth token which then can be passed to the later commands. You need to authenticate against VCD first to get a session token.

# curl -sik -H “Accept:application/*+xml;version=5.6” -u “Administrator@system:Administrator password” -X POST https://vCloud Director FQDN]/api/sessions

Example

[code]

curl -sik -H "Accept:application/*+xml;version=5.6" -u "admin@system" -X POST https://p15v3-vcd.vchs.vmware.com/api/sessions | grep auth

Enter host password for user ‘admin@system’:

x-vcloud-authorization: d18d26b54cb346c8a9a097ab24d7edf

[/code]

Once you receive auth token, we have to change the header in above command to:

“x-vcloud-authorization: Auth Token”

2: Get Otg UUID

Next is to grab the Org UUID by executing below command:

# curl -sik -H “Accept:application/*+xml;version=5.6” -H “x-vcloud-authorization: d18d26b54cb346c8a9a097ab24d7edf” -X GET https://p15v3-vcd.vchs.vmware.com/api/org/ | grep bdd75fd4-a319-47d5-b4f2-77aad691488f

The above command will give you href to org URL

[code]

<Org href="https://au-south-1-15.vchs.vmware.com/api/compute/api/org/4f5feba5-bb82-456e-8898-95d4970f2624" name="bdd75fd4-a319-47d5-b4f2-77aad691488f" type="application/vnd.vmware.vcloud.org+xml"/>

[/code]

3: Get Org VDC UUID

# curl -sik -H “Accept:application/*+xml;version=5.6” -H “x-vcloud-authorization: d18d26b54cb346c8a9a097ab24d7edf” -X GET https://au-south-1-15.vchs.vmware.com/api/compute/api/org/4f5feba5-bb82-456e-8898-95d4970f2624 | grep vdc

[/code]

<Link rel=”down” href=”https://au-south-1-15.vchs.vmware.com/api/compute/api/vdc/89ca1c69-0ea1-47f3-b3c1-e91608908966″ name=”Manish-Lab-DontDel” type=”application/vnd.vmware.vcloud.vdc+xml”/>

[/code]

4: Get list of vApps

curl -sik -H “Accept:application/*+xml;version=5.6” -H “x-vcloud-authorization: d18d26b54cb346c8a9a097ab24d7edf” -X GET https://au-south-1-15.vchs.vmware.com/api/compute/api/vdc/89ca1c69-0ea1-47f3-b3c1-e91608908966 | grep vapp

The above command will give you full list of all the vApps which you have created in vCD

[code]

<ResourceEntity href="https://au-south-1-15.vchs.vmware.com/api/compute/api/vAppTemplate/vappTemplate-d4c9d90b-e3ae-4d8a-ae46-25d4fd309d97" name="Esxi" type="application/vnd.vmware.vcloud.vAppTemplate+xml"/>

<ResourceEntity href="https://au-south-1-15.vchs.vmware.com/api/compute/api/vApp/vapp-5960b14b-792b-40fc-8fba-ecfe3673050a" name="Openfiler" type="application/vnd.vmware.vcloud.vApp+xml"/>

<ResourceEntity href="https://au-south-1-15.vchs.vmware.com/api/compute/api/vApp/vapp-87ec9f6d-75e1-4556-b5e9-3a2ac10a7228" name="CASRV01-VApp" type="application/vnd.vmware.vcloud.vApp+xml"/>

<ResourceEntity href="https://au-south-1-15.vchs.vmware.com/api/compute/api/vApp/vapp-9d49c9e6-f730-47d8-893e-1bbd11b3796d" name="Esxi-2" type="application/vnd.vmware.vcloud.vApp+xml"/>

<ResourceEntity href="https://au-south-1-15.vchs.vmware.com/api/compute/api/vApp/vapp-a2f884f2-9e4b-45a2-9d22-0c62697c1a76" name="vCenterSrv" type="application/vnd.vmware.vcloud.vApp+xml"/>

<ResourceEntity href="https://au-south-1-15.vchs.vmware.com/api/compute/api/vApp/vapp-aac557fc-3145-43e1-a1bf-f6de7ad5ff48" name="Esxi-1" type="application/vnd.vmware.vcloud.vApp+xml"/>

<ResourceEntity href="https://au-south-1-15.vchs.vmware.com/api/compute/api/vApp/vapp-213b94b4-ef32-4ce6-8157-b8e131eb7e45" name="Alex-DC-VApp" type="application/vnd.vmware.vcloud.vApp+xml"/>

&nbsp;

[/code]

5: Get VM UUID

Since now we have href to the vApps, we can now get UUID of the VM which we are planning to move to other datastore.

# curl -sik -H “Accept:application/*+xml;version=5.6” -H “x-vcloud-authorization: d18d26b54cb346c8a9a097ab24d7edf” -X GET https://au-south-1-15.vchs.vmware.com/api/compute/api/vApp/vapp-213b94b4-ef32-4ce6-8157-b8e131eb7e45

https://au-south-1-15.vchs.vmware.com/api/compute/api/vApp/vm-1c0577e0-ca4b-4187-8e2f-3bad46ab0649

6: Get list of datastores

# curl -sik -H “Accept:application/*+xml;version=5.6” -H “x-vcloud-authorization: d18d26b54cb346c8a9a097ab24d7edf” -X GET https://p15v3-vcd.vchs.vmware.com/api/query?type=datastore

This query will return a lot of info about the datastores like provisioned storage, used space, free space available on datastore, datastore Mo-ref and href to datastores.

[/code]

<DatastoreRecord datastoreType=”VMFS5″ isDeleted=”false” isEnabled=”true” moref=”datastore-108014″ name=”z_d10p15s3vnx0lu66_tStd_inuse” numberOfProviderVdcs=”1″ provisionedStorageMB=”13059087″ requestedStorageMB=”6521317″ storageMB=”10485504″ storageUsedMB=”7595588″ vc=”https://au-south-1-15.vchs.vmware.com/api/compute/api/admin/extension/vimServer/3dba3aa4-9897-46bf-b306-e28bc74d4245″ vcName=”vc-fqdn” href=”https://au-south-1-15.vchs.vmware.com/api/compute/api/admin/extension/datastore/019650ee-d210-4a9e-beb6-6305fb325f78“/>

<DatastoreRecord datastoreType=”VMFS5″ isDeleted=”false” isEnabled=”true” moref=”datastore-19022″ name=”z_d10p15s3vnx0lu57_tSSDAcc_inuse” numberOfProviderVdcs=”1″ provisionedStorageMB=”7991302″ requestedStorageMB=”8479229″ storageMB=”10485504″ storageUsedMB=”2016348″ vc=”https://au-south-1-15.vchs.vmware.com/api/compute/api/admin/extension/vimServer/3dba3aa4-9897-46bf-b306-e28bc74d4245″ vcName=”vc-fqdn” href=”https://au-south-1-15.vchs.vmware.com/api/compute/api/admin/extension/datastore/2d332c98-dca8-4966-8a82-010107873b9c“/>

<DatastoreRecord datastoreType=”VMFS5″ isDeleted=”false” isEnabled=”true” moref=”datastore-17670″ name=”z_d10p15s3vnx0lu51_tStd_inuse” numberOfProviderVdcs=”1″ provisionedStorageMB=”12538920″ requestedStorageMB=”10196156″ storageMB=”10485504″ storageUsedMB=”6006352″ vc=”https://au-south-1-15.vchs.vmware.com/api/compute/api/admin/extension/vimServer/3dba3aa4-9897-46bf-b306-e28bc74d4245″ vcName=”vc-fqdn” href=”https://au-south-1-15.vchs.vmware.com/api/compute/api/admin/extension/datastore/04c95861-ba67-4f14-be20-80564c622fb5“/>

<DatastoreRecord datastoreType=”VMFS5″ isDeleted=”false” isEnabled=”true” moref=”datastore-17671″ name=”z_d10p15s3vnx0lu56_tSSDAcc_inuse” numberOfProviderVdcs=”1″ provisionedStorageMB=”8810546″ requestedStorageMB=”8773278″ storageMB=”10485504″ storageUsedMB=”7094757″ vc=”https://au-south-1-15.vchs.vmware.com/api/compute/api/admin/extension/vimServer/3dba3aa4-9897-46bf-b306-e28bc74d4245″ vcName=”vc-fqdn” href=”https://au-south-1-15.vchs.vmware.com/api/compute/api/admin/extension/datastore/25600d4b-144e-4561-9d67-e68b0cca0f04“/>

<DatastoreRecord datastoreType=”VMFS5″ isDeleted=”false” isEnabled=”true” moref=”datastore-19203″ name=”z_d10p15s3vnx0lu58_tSSDAcc_inuse” numberOfProviderVdcs=”1″ provisionedStorageMB=”6293195″ requestedStorageMB=”6070760″ storageMB=”10485504″ storageUsedMB=”2509893″ vc=”https://au-south-1-15.vchs.vmware.com/api/compute/api/admin/extension/vimServer/3dba3aa4-9897-46bf-b306-e28bc74d4245″ vcName=”vc-fqdn” href=”https://au-south-1-15.vchs.vmware.com/api/compute/api/admin/extension/datastore/2708a5ca-c9f0-4dcc-a343-9289d34b8435“/>

<DatastoreRecord datastoreType=”VMFS5″ isDeleted=”false” isEnabled=”true” moref=”datastore-66433″ name=”z_d10p15s3vnx0lu65_tStd_inuse” numberOfProviderVdcs=”1″ provisionedStorageMB=”7326909″ requestedStorageMB=”4607043″ storageMB=”10485504″ storageUsedMB=”3819394″ vc=”https://au-south-1-15.vchs.vmware.com/api/compute/api/admin/extension/vimServer/3dba3aa4-9897-46bf-b306-e28bc74d4245″ vcName=”vc-fqdn” href=”https://au-south-1-15.vchs.vmware.com/api/compute/api/admin/extension/datastore/2a1ac7a6-6c25-4fb2-9b70-217850b78bfe“/>

[/code]

7: Find out datastore name where your VM is residing

To do this, dump the VM settings into an xml file and grep for datastore.

# curl -sik -H “Accept:application/*+xml;version=5.6” -H “x-vcloud-authorization: d18d26b54cb346c8a9a097ab24d7af0c” -X GET https://au-south-1-15.vchs.vmware.com/api/compute/api/vApp/vm-1c0577e0-ca4b-4187-8e2f-3bad46ab0649 > vminfo.xml

# cat vminfo.xml | grep datastore

<vmext:MoRef>datastore-19203</vmext:MoRef>

<vmext:MoRef>datastore-19203</vmext:MoRef>

<vmext:MoRef>datastore-19203</vmext:MoRef>

You can match the Mo-Ref returned with output of query 6 and you will know the name of the datastore where your VM is presently residing.

8: Prepare for migration

Now before we start migration, we need to create an input file which contains the destination datastore UUID where we want to send the VM. We will supply the input file alongwith API query to perform the storage migration.

Note: In output of query 6, we got a bunch of datastore alongwith details of free space on each datastore. You can select that datastore which has  max available free space.

Info about the necessary parameters can be obtained from API Schema guide

I created a file named ‘dest-ds.xml’ with below content:

<?xml version=”1.0″ encoding=”UTF-8″?>
<RelocateParams xmlns=”http://www.vmware.com/vcloud/v1.5″>
<Datastore href=”https://au-south-1-15.vchs.vmware.com/api/compute/api/admin/extension/datastore/2d332c98-dca8-4966-8a82-010107873b9c” />
</RelocateParams>

Make sure formatting is correct in the xml file else you will get error. My XML file looks like

sv-3

If you have trouble with xml formatting, you can go to Online XML formatter and paste your text in XML Formatter area and click on Format XML

sv-0

You will see the formatted xml as output

xml-0

9: Perform the migration of VM

# curl -sik -H “Accept:application/*+xml;version=5.6” -H “x-vcloud-authorization: d18d26b54cb346c8a9a097ab24d7af0c” -H “Content-Type:application/vnd.vmware.vcloud.relocateVmParams+xml” -d @dest-ds.txt -X POST https://au-south-1-15.vchs.vmware.com/api/compute/api/vApp/vm-1c0577e0-ca4b-4187-8e2f-3bad46ab0649/action/relocate 

The above will generate a task id:

HTTP/1.1 202 Accepted
Date: Sat, 24 Dec 2016 13:39:22 GMT
Strict-Transport-Security: max-age=15768000; includeSubDomains
X-Frame-Options: SAMEORIGIN
X-VMWARE-VCLOUD-REQUEST-ID: XXXXXXXX
x-vcloud-authorization: XXXXXXX
X-VMWARE-VCLOUD-REQUEST-EXECUTION-TIME: 229
Location: https://au-south-1-15.vchs.vmware.com/api/compute/api/task/d17538e6-7fb6-480f-bf7c-a4e11cfc0c83

If you have access to backend vSphere, you can see the migration task there

 

sv-2

In case if you dont have access to backend, you can monitor the migration process by using below query

# curl -sik -H “Accept:application/*+xml;version=5.6” -H “x-vcloud-authorization: d18d26b54cb346c8a9a097ab24d7af0c” -X GET https://au-south-1-15.vchs.vmware.com/api/compute/api/task/d17538e6-7fb6-480f-bf7c-a4e11cfc0c83 | grep Progress

<Progress>100</Progress>

if the progress reads 100, it means migration have been completed.

I hope this post is informational to you. Feel free to share this on social media if it is worth sharing. Be sociable 🙂

 

Leave a reply