Skip to content

Create Scratch Vapp Example

Nick Kasprzak edited this page Apr 1, 2019 · 13 revisions

Introduction

This is a guide to take you through building your own project from scratch, building a scratch vApp through iland's Java SDK.

If you have git cloned the Java SDK project then you can just cd into the create-scratch-vapp directory and follow along.

Creating vApps and VMs

In this example we are trying to create a virtual machine so we will need to use the resources that allow us to do that.

Here is the link to our documentation that shows all the resources we can use with the SDK.

For this example we will need these resources:

  • UserResource
  • VdcResource
  • TaskResource

To instantiate an API resource is easy with the Client we created earlier. All you need to do is this:

UserResource userResource = apiClient.getUserResource();
VdcResource vappResource = apiClient.getVdcResource();
TaskResource taskResouce = apiClient.getTaskResource();

Now we can use the functions in these resource objects to create a vApp.

To create a vApp either from scratch of from an existing vapp template we must use the VdcResource.

Within the VdcResource we have either the option of using the functions addVappFromTemplate or buildVapp. To find what functions VdcResource has look in the documentation here.

Let's use buildVapp to build a vApp from scratch.

Looking at buildVapp parameters we see that it takes a String called vdcUuid and a BuildVappRequest object called spec.

Now how do you know what the vdcUuid is? Or better question which ones you have permissions to use?

Well in UserResource we have a function called getInventory(). It takes two parameters, the username and the companyId. If you don't specify the companydId then it will get all the inventory the user has permission for every company that user belongs to.

So let's the get the user's inventory with the following code:

UserInventoryResponse userInventory = userResource.getInventory(USERNAME, null);

This returns an object called UserInventoryResponse, if we look at the documentation for this object here we can see that the response object has a list of objects called UserCompanyInventoryResponse.

These objects represent each company the user has permissions to and within them is a Map of IamEntityType to a list of UserInventoryEntityResponse.

So by iterating through the UserCompanyInventoryResponse objects we can find the vDCs the user has permission to and print out their UUIDs and names.

Here's how to do that:

for (UserCompanyInventoryResponse companyInventory : userInventory.getInventory()) {
    if(copmanyInventory.getEntities() != null && !copmanyInventory.getEntities().isEmpty()) {
        List<UserInventoryEntityResponse> vDCS = companyInventory.getEntities().get(IamEntityType.IAAS_VDC);
        for (UserInventoryEntityResponse vDC : vDCS) {
             System.out.println(String.format("vDC name: %s, UUID: %s", vDC.getName(), vDC.getUuid()));
        }
    }
}

If you build the project and run the java -jar command from earlier, you will print out all the vDC names and uuids your user has permission for.

Instead of printing all of them out, let's just grab one so we can use it to create a vApp.

Declare a String vdcUuid = ""; outside of the for loops and replace the System.out.println() with the following code:

vdcUuid = vDC.getUuid();
break;

Now we have a vDC uuid, let's look at the BuildVappRequest spec parameter.

Looking at the documentation here, we see that the BuildVappRequest object takes a String name, a String description and a List of BuildVmRequest called vms. We can build a very basic vAppp with no VMs with the following code.

BuildVappRequest vappRequest = new BuildVappRequest("vapp_name", "vapp_description", Collections.emptyList());
TaskResponse taskResponse = vdcResource.buildVapp(TestVDCs.PAYG, vappRequest);

This code creates a bare bones vApp in the vDC with no VMs. It just has the name and description you provide. The function buildVapp returns a TaskResponse that I will address later.

Note: vApp names must be unique. You will get an error if you try making a vApp with the same name as an existing vApp.

To build a vApp that has VMs we must the BuildVmRequest object. From the documentation of BuildVmRequest here we can see the constructor of BuildVmRequest is the following:

BuildVmRequest(String name, String description, String vmTemplateUuid, String vappTemplateUuid, List<VmDiskRequest> disks, Integer ram, Integer numberOfCpus, Integer cpuCoresPerSocket, Integer hardwareVersion, String operatingSystemVersion, Integer bootDelay, Boolean exposeCpuVirtualization, String mediaUuid, String computerName, String storageProfileUuid, List<VmVnicRequest> vnics) 

So in our code when we want to build a VM from scratch we must fill in the parameters we need for BuildVmRequest, put it into an ArrayList and pass it in buildVapp().

With the BuildVmRequest there are countless ways to customize the VMs you want to create. Here's an example of a basic VM you can create:

String vmName = "Example Scratch Vapp";
String vmDescription = "vApp's description";
Integer ram = 2000;
Integer numOfCpus = 4;
Integer cpuCoresPerSocket = 2;
Integer hardwareVersion = 11;
String operatingSystem = "ubuntu64Guest";
Integer bootDelay = 0;
boolean exposeCpuVirtualization = true;
final BuildVmRequest scratchVm =
        new BuildVmRequest(vmName, vmDescription, null, null, null, ram,
            numOfCpus, cpuCoresPerSocket, hardwareVersion, operatingSystem, bootDelay,
            exposeCpuVirtualization, null, "testComName", null, null);

This creates a basic Ubuntu VM with the specific details that I specified in the spec.

Note: All of the fields I included for the scratch VM are required. If you don't provide any of these you will get an error back from our API that they are required.

If you want to figure out which operating systems and what to pass for them look at ConstantsResource function getOperatingSystems.

Handling tasks

As you can tell from the code, the buildVapp endpoint returns something called a TaskResponse.

A TaskResponse represents the task that tracks the progress of whatever you called from the API, in this case it tracks the creation of the vApp.

The TaskResponse is very useful because it contains information like the progress of the task, whether the task succeeded and messages of errors that might have occurred.

We will write a function that helps just check whether or not the task has been synced by querying the TaskResource for a given interval.

private static void waitForSyncedTask(final String taskUuid) {
    boolean synced = false;
    TaskResponse coreTask;
    while (!synced) {
      try {
        // Thread sleep takes time in milliseconds, here we wait 2 seconds before checking to see if the task has synced yet. 
        Thread.sleep(2000);
      } catch (final InterruptedException e) {
        System.out.println(String.format("Error while waiting for task=%s. %s",taskUuid, e.getMessage()));
      }
      coreTask = taskResource.getTask(taskUuid);
      synced = coreTask.isSynced();
    }
}

So now that the task is synced we can get it again and check if it succeeded by using the following code:

TaskResponse syncedBuildVappTask = taskResource.getTask(buildVappTask.getUuid());
    if (syncedBuildVappTask.getStatus().equals("ERROR")) {
      System.out.println(syncedBuildVappTask.getMessage());
    }

If nothing is printed we know that the vApp and VM have been created successfully.