You can capture a virtual machine using the API and once you get started, it's not such a daunting task as it might first seem! And as always, if you get stuck, you can always open your browser console and take a look at how the Abiquo UI does it!
Before you get started, make sure you are familiar with the capture process in the UI. Also you will need to prepare a suitable environment, with a virtual datacenter and a matching network for the VM. See Import and Capture Virtual Machines. Note that the Abiquo UI enables you to create a virtual appliance or a network address as part of the capture process but these steps are not included in this tutorial.
To work through this tutorial you can use a cloud admin account with basic authentication, but this is not recommended in a production environment, see Authentication.
To capture a VM using the API:
- Retrieve the virtual appliance that the VM will be captured into
- Retrieve the VM with resources from the hypervisor in Abiquo
- Retrieve the network addresses from the platform and add them to the VM object
- Send a POST request with the VM object to virtual machines URL of the virtual appliance
Retrieve the virtual appliance
The first step is to List virtual appliances in your virtual datacenter and locate the virtual appliance where you will add the VM.
If you don't have the link to virtual appliances, first List virtual datacenters, and look for the "href" value of the virtualappliances link
curl -X GET https://example.com/api/cloud/virtualdatacenters/2/virtualappliances \ -H 'Accept:application/vnd.abiquo.virtualappliances+json; version=4.2' \ -u user:password --verbose
From the virtual appliance objects, look for your virtual appliance, and find the virtualmachines link.
To create the VM in the platform, we will send a POST request to this link.
{ "title": "virtual machines", "rel": "virtualmachines", "type": "application/vnd.abiquo.virtualmachines+json", "href": "https://example.com:443/api/cloud/virtualdatacenters/2/virtualappliances/2/virtualmachines" },
Now let's create the VM data object that we will send with the post request.
Retrieve the VM with resources from the hypervisor
For this step, we will need to know how to locate and identify the VM in infrastructure. One easy way to do this is to open the UI console at the Network tab, and select the machine that the VM is running on. To obtain data about the infrastructure, the UI will be making GET requests to links like the following one.
https://example.com/api/admin/datacenters/4/racks/4/machines/2/virtualmachines?cacheStamp=361_1516271112132
To retrieve all the VMs that are running on this machine but are not registered in Abiquo, use the query parameter "sync" with a value of true.
curl -X GET https://example.com/api/admin/datacenters/4/racks/4/machines/2/virtualmachines?sync=true \ -H 'Accept:application/vnd.abiquo.virtualmachines+json; version=4.2' \ -u user:password --verbose
Then search for your VM in the response and obtain the "virtualmachine" link
So our VM with the name starting with "ABQ_14c4aa8c" is number 265 in infrastructure, and its link is as follows.
{ "title": "ABQ_14c4aa8c-5ee4-49f5-b9e7-596e332d90a8", "rel": "virtualmachine", "type": "application/vnd.abiquo.virtualmachine+json", "href": "https://example.com:443/api/admin/datacenters/4/racks/4/machines/2/virtualmachines/265" }
Now retrieve the "virtualmachineflat" data object. This is a VM with all resources inline, including the network interface cards (NICs). Here we use the sync parameter with a value of true to obtain the latest information from the hypervisor.
curl -X GET https://example.com/api/admin/datacenters/4/racks/4/machines/2/virtualmachines/265?sync=true \ -H 'Accept:application/vnd.abiquo.virtualmachineflat+json; version=4.2' \ -u user:password --verbose
This is our base virtualmachine flat object and as you can see there is no IP address for the NIC, so we will add that next.
Retrieve network details and IP addresses
In this tutorial we are going to work with an external network. This is the most flexible network type, because you can use public or private addresses and each external network is only available to the enterprise tenant that it belongs to. If you want to use a public network, you will need to purchase a public IP address for your virtual datacenter before you can add it to the VM.
External networks belong to a single enterprise, so you can open the browser console to the Networks tab and go to the Users view in the UI to find your enterprise ID number. When you select the enterprise, you should see a request to a link like the following one.
https://example.com/api/admin/enterprises/2/users?maxSize=5&maxSizeMini=1¤tPage=1&limit=25&startwith=0&totalSize=0&asc=true&connected=false&cacheStamp=755_1516274214060
Now use the enterprises link to get the enterprise data object.
curl -X GET https://example.com/api/admin/enterprises/2 \ -H 'Accept:application/vnd.abiquo.enterprise+json; version=4.2' \ -u user:password --verbose
From the enterprise, get the link to the enterprise limits.
{ "title": "limits", "rel": "limits", "type": "application/vnd.abiquo.limits+json", "href": "https://example.com:443/api/admin/enterprises/2/limits" },
Then perform a GET request to retrieve the limits. There is one limit for each datacenter or public cloud region that your enterrpise is allowed to use. This is because in the API, to allow an enterprise to use a datacenter, you create a datacenter limit for the enterprise.
So in this example, the enteprise is allowed to use a private cloud datacenter, called "BCDC" and a public cloud region, called "aws".
Identify the limit for the datacenter you accessed in the previous steps, for example, here is the link identifying the datacenter within the limit. This limit has an ID with a value of "5".
{ "title": "BCDC", "rel": "location", "type": "application/vnd.abiquo.datacenter+json", "href": "https://example.com:443/api/admin/datacenters/4" },
For this limit, select the link to its external networks.
{ "title": "external networks", "rel": "externalnetworks", "type": "application/vnd.abiquo.vlans+json", "href": "https://example.com:443/api/admin/enterprises/2/limits/5/externalnetworks" },
Then perform a get request to retrieve the external networks.
curl -X GET https://example.com/api/admin/enterprises/2/limits/5/externalnetworks \ -H 'Accept:application/vnd.abiquo.vlans+json; version=4.2' \ -u user:password --verbose
From the external networks object, find the link to IPs.
{ "title": "ips", "rel": "ips", "type": "application/vnd.abiquo.externalips+json", "href": "https://example.com:443/api/admin/enterprises/2/limits/5/externalnetworks/7/ips" },
And perform a GET request to retrieve the IPs.
curl -X GET https://example.com/api/admin/enterprises/2/limits/5/externalnetworks/7/ips \ -H 'Accept:application/vnd.abiquo.externalips+json; version=4.2' \ -u user:password --verbose
Select the IP address that you would like to add to the VM.
Create the virtualmachineflat data object
Now go back and get the virtualmachineflat object that you retrieved from the hypervisor. Find the edit link (the "rel" value will be edit and copy it to create two links. Change the "rel" value of the first link to "virtualmachine" and the second one to "imported".
In the NICs section of the VM, add links to the VLAN. For example, for the external IP address, obtain the link with a "rel" value of "externalnetwork".
{ "title": "External_network", "rel": "externalnetwork", "type": "application/vnd.abiquo.vlan+json", "href": "https://example.com:443/api/admin/enterprises/2/limits/5/externalnetworks/7" },
And change the value of the "rel" attribute to "vlan"
{ "title": "External_network", "rel": "vlan", "type": "application/vnd.abiquo.vlan+json", "href": "https://example.com:443/api/admin/enterprises/2/limits/5/externalnetworks/7" },
And note the IP address you would like to add
"ip": "192.168.7.2",
Edit the VM NIC(s) and add the link(s) to the "nics" - "collection" - "links" section for each NIC and the IP to the main section of each NIC after the tag value (don't forget the comma).
Finally your data object should be similar to the one in the following example.
Capture the virtual machine
To capture the VM machine, send a POST request to the virtualmachines URL of the virtual appliance that will hold the captured VM. Use the virtualmachineflat data transfer object that you created in the previous step as the data object.
curl -X POST http://example.com/api/cloud/virtualdatacenters/2/virtualappliances/2/virtualmachines \ -H 'Accept:application/vnd.abiquo.virtualmachineflat+json; version=4.2' \ -H 'Content-Type:application/vnd.abiquo.virtualmachineflat+json; version=4.2' \ -d @requestpayload.json \ -u user:password --verbose
The virtualmachineflat object that you should send in the requestpayload.json file should be similar to the following example.
If the request is successful, a 201 code should be returned, as well as the virtualmachineflat data object that was created.
Now Abiquo should display your VM as a managed VM and you should be able to find it in the virtual datacenter.