@Test(enabled = true, dependsOnMethods = "testConcurrentUseOfComputeServiceToCreateNodes")
  public void testCreateTwoNodesWithRunScript() throws Exception {
    try {
      client.destroyNodesMatching(inGroup(group));
    } catch (NoSuchElementException e) {

    }
    refreshTemplate();
    try {
      nodes = newTreeSet(client.createNodesInGroup(group, 2, template));
    } catch (RunNodesException e) {
      nodes = newTreeSet(concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet()));
      throw e;
    }

    assertEquals(nodes.size(), 2, "expected two nodes but was " + nodes);
    checkNodes(nodes, group, "bootstrap");
    NodeMetadata node1 = nodes.first();
    NodeMetadata node2 = nodes.last();
    // credentials aren't always the same
    // assertEquals(node1.getCredentials(), node2.getCredentials());

    assertLocationSameOrChild(
        checkNotNull(node1.getLocation(), "location of %s", node1), template.getLocation());
    assertLocationSameOrChild(
        checkNotNull(node2.getLocation(), "location of %s", node2), template.getLocation());
    checkImageIdMatchesTemplate(node1);
    checkImageIdMatchesTemplate(node2);
    checkOsMatchesTemplate(node1);
    checkOsMatchesTemplate(node2);
  }
 private Set<RunningInstance> createKeyPairAndSecurityGroupsAsNeededThenRunInstances(
     String group, int count, Template template) {
   String region = AWSUtils.getRegionFromLocationOrNull(template.getLocation());
   String zone = getZoneFromLocationOrNull(template.getLocation());
   RunInstancesOptions instanceOptions =
       createKeyPairAndSecurityGroupsAsNeededAndReturncustomize.execute(region, group, template);
   return createNodesInRegionAndZone(region, zone, group, count, template, instanceOptions);
 }
  @Test(enabled = true, dependsOnMethods = "testTemplateMatch")
  public void testCreateTwoNodesWithRunScript() throws Exception {
    try {
      client.destroyNodesMatching(NodePredicates.withTag(tag));
    } catch (HttpResponseException e) {
      // TODO hosting.com throws 400 when we try to delete a vApp
    } catch (NoSuchElementException e) {

    }
    template = buildTemplate(client.templateBuilder());

    template
        .getOptions()
        .installPrivateKey(keyPair.get("private"))
        .authorizePublicKey(keyPair.get("public"))
        .runScript(buildScript(template.getImage().getOsFamily()).getBytes());
    try {
      nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 2, template));
    } catch (RunNodesException e) {
      nodes = Sets.newTreeSet(Iterables.concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet()));
      throw e;
    }
    assertEquals(nodes.size(), 2);
    checkNodes(nodes, tag);
    NodeMetadata node1 = nodes.first();
    NodeMetadata node2 = nodes.last();
    // credentials aren't always the same
    // assertEquals(node1.getCredentials(), node2.getCredentials());

    assertLocationSameOrChild(node1.getLocation(), template.getLocation());
    assertLocationSameOrChild(node2.getLocation(), template.getLocation());

    assertEquals(node1.getImage(), template.getImage());
    assertEquals(node2.getImage(), template.getImage());
  }
  @Test(
      enabled = true,
      dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
  public void testGet() throws Exception {
    Map<String, ? extends NodeMetadata> metadataMap =
        newLinkedHashMap(
            uniqueIndex(
                filter(client.listNodesDetailsMatching(all()), and(withTag(tag), not(TERMINATED))),
                new Function<NodeMetadata, String>() {

                  @Override
                  public String apply(NodeMetadata from) {
                    return from.getId();
                  }
                }));
    for (NodeMetadata node : nodes) {
      metadataMap.remove(node.getId());
      NodeMetadata metadata = client.getNodeMetadata(node.getId());
      assertEquals(metadata.getProviderId(), node.getProviderId());
      assertEquals(metadata.getTag(), node.getTag());
      assertLocationSameOrChild(metadata.getLocation(), template.getLocation());
      checkImageIdMatchesTemplate(metadata);
      checkOsMatchesTemplate(metadata);
      assertEquals(metadata.getState(), NodeState.RUNNING);
      // due to DHCP the addresses can actually change in-between runs.
      assertEquals(metadata.getPrivateAddresses().size(), node.getPrivateAddresses().size());
      assertEquals(metadata.getPublicAddresses().size(), node.getPublicAddresses().size());
    }
    assertNodeZero(metadataMap.values());
  }
  @Test(enabled = true, dependsOnMethods = "testCompareSizes")
  public void testCreateTwoNodesWithRunScript() throws Exception {
    try {
      client.destroyNodesMatching(withTag(tag));
    } catch (NoSuchElementException e) {

    }
    refreshTemplate();
    try {
      nodes = newTreeSet(client.runNodesWithTag(tag, 2, template));
    } catch (RunNodesException e) {
      nodes = newTreeSet(concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet()));
      throw e;
    }
    assertEquals(nodes.size(), 2);
    checkNodes(nodes, tag);
    NodeMetadata node1 = nodes.first();
    NodeMetadata node2 = nodes.last();
    // credentials aren't always the same
    // assertEquals(node1.getCredentials(), node2.getCredentials());

    assertLocationSameOrChild(node1.getLocation(), template.getLocation());
    assertLocationSameOrChild(node2.getLocation(), template.getLocation());
    checkImageIdMatchesTemplate(node1);
    checkImageIdMatchesTemplate(node2);
    checkOsMatchesTemplate(node1);
    checkOsMatchesTemplate(node2);
  }
 @Test
 public void testTemplateBuilder() {
   Template defaultTemplate = client.templateBuilder().build();
   assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
   assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
   assertEquals(defaultTemplate.getLocation().getDescription(), "Miami Environment 1");
   assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
 }
 @Test
 public void testTemplateBuilder() {
   Template defaultTemplate = this.context.getComputeService().templateBuilder().build();
   assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
   assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04");
   assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
   assertEquals(defaultTemplate.getLocation().getId(), "elastichosts-lon-p");
   assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
 }
 @Test
 public void testTemplateBuilder() {
   Template defaultTemplate = view.getComputeService().templateBuilder().build();
   assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
   assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "11.04");
   assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
   assertEquals(defaultTemplate.getLocation().getId(), "DCDALLAS");
   assertEquals(defaultTemplate.getHardware().getProviderId(), "MIRO4B");
   assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
 }
 @Test(enabled = true, dependsOnMethods = "testCreateTwoNodesWithRunScript")
 public void testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired() throws Exception {
   initializeContextAndClient();
   TreeSet<NodeMetadata> nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 1, template));
   checkNodes(nodes, tag);
   NodeMetadata node = nodes.first();
   this.nodes.add(node);
   assertEquals(nodes.size(), 1);
   assertLocationSameOrChild(node.getLocation(), template.getLocation());
   assertEquals(node.getImage(), template.getImage());
 }
  @Test(enabled = true, dependsOnMethods = "testCreateTwoNodesWithOneSpecifiedName")
  public void testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired() throws Exception {
    initializeContext();

    Location existingLocation = Iterables.get(this.nodes, 0).getLocation();
    boolean existingLocationIsAssignable =
        Iterables.any(client.listAssignableLocations(), Predicates.equalTo(existingLocation));

    if (existingLocationIsAssignable) {
      getAnonymousLogger()
          .info("creating another node based on existing nodes' location: " + existingLocation);
      template = buildTemplate(client.templateBuilder());
      template =
          addRunScriptToTemplate(
              client
                  .templateBuilder()
                  .fromTemplate(template)
                  .locationId(existingLocation.getId())
                  .build());
    } else {
      refreshTemplate();
      getAnonymousLogger()
          .info(
              format(
                  "%s is not assignable; using template's location %s as  ",
                  existingLocation, template.getLocation()));
    }

    Set<? extends NodeMetadata> nodes = client.createNodesInGroup(group, 1, template);
    assertEquals(nodes.size(), 1);
    checkNodes(nodes, group, "bootstrap");
    NodeMetadata node = Iterables.getOnlyElement(nodes);
    if (existingLocationIsAssignable) assertEquals(node.getLocation(), existingLocation);
    else
      this.assertLocationSameOrChild(
          checkNotNull(node.getLocation(), "location of %s", node), template.getLocation());
    checkOsMatchesTemplate(node);
    this.nodes.add(node);
  }
  @Test
  public void testTemplateBuilderCanUseImageId() {
    Template defaultTemplate = context.getComputeService().templateBuilder().build();

    Template template =
        context
            .getComputeService()
            .templateBuilder()
            .imageId(defaultTemplate.getImage().getId())
            .locationId(defaultTemplate.getLocation().getId())
            .build();
    assertEquals(template.getImage(), defaultTemplate.getImage());
  }
  private void setSecurityGroupOnTemplate(
      final JcloudsLocation location,
      final Template template,
      final SecurityGroupExtension securityApi) {
    SecurityGroup shared;
    Tasks.setBlockingDetails(
        "Loading security group shared by instances in "
            + template.getLocation()
            + " in app "
            + applicationId);
    try {
      shared =
          sharedGroupCache.get(
              template.getLocation(),
              new Callable<SecurityGroup>() {
                @Override
                public SecurityGroup call() throws Exception {
                  return getOrCreateSharedSecurityGroup(template.getLocation(), securityApi);
                }
              });
    } catch (ExecutionException e) {
      throw Throwables.propagate(new Exception(e.getCause()));
    } finally {
      Tasks.resetBlockingDetails();
    }

    Set<String> originalGroups = template.getOptions().getGroups();
    template.getOptions().securityGroups(shared.getName());
    if (!originalGroups.isEmpty()) {
      LOG.info(
          "Replaced configured security groups: configured={}, replaced with={}",
          originalGroups,
          template.getOptions().getGroups());
    } else {
      LOG.debug(
          "Configured security groups at {} to: {}", location, template.getOptions().getGroups());
    }
  }
  @Override
  public NodeAndInitialCredentials<VM> createNodeWithGroupEncodedIntoName(
      String tag, String name, Template template) {
    String networkTierName = template.getLocation().getId();
    String vpdcId = template.getLocation().getParent().getId();
    String billingSiteId = template.getLocation().getParent().getParent().getId();

    VMSpec.Builder specBuilder = VMSpec.builder();
    specBuilder.name(name);
    specBuilder.networkTierName(networkTierName);
    specBuilder.operatingSystem(
        CIMOperatingSystem.class.cast(template.getImage().getOperatingSystem()));
    specBuilder.processorCount(template.getHardware().getProcessors().size());
    specBuilder.memoryInGig(template.getHardware().getRam() / 1024);

    for (Volume volume : template.getHardware().getVolumes()) {
      if (volume.isBootDevice())
        specBuilder.bootDeviceName(volume.getDevice()).bootDiskSize(volume.getSize().intValue());
      else specBuilder.addDataDrive(volume.getDevice(), volume.getSize().intValue());
    }

    Task task = client.getVMClient().addVMIntoVDC(billingSiteId, vpdcId, specBuilder.build());
    // make sure there's no error
    if (task.getError() != null)
      throw new RuntimeException("cloud not add vm: " + task.getError().toString());

    if (taskTester.apply(task.getId())) {
      try {
        VM returnVal = this.getNode(task.getResult().getHref().toASCIIString());
        return new NodeAndInitialCredentials<VM>(returnVal, returnVal.getId(), null);
      } finally {
        // TODO: get the credentials relevant to the billingSiteId/Org
        // credentialStore.put(id, new Credentials(orgId, orgUser));
      }
    } else {
      throw new RuntimeException("task timed out: " + task);
    }
  }
  @Test
  public void testTemplateBuilderCanUseImageId() throws Exception {
    Template defaultTemplate = context.getComputeService().templateBuilder().build();
    context.close();
    setupClient();

    Template template =
        context
            .getComputeService()
            .templateBuilder()
            .imageId(defaultTemplate.getImage().getId())
            .locationId(defaultTemplate.getLocation().getId())
            .build();
    assertEquals(template.getImage(), defaultTemplate.getImage());
  }
 @Test
 public void testDefaultTemplateBuilder() throws IOException {
   Template defaultTemplate = this.context.getComputeService().templateBuilder().build();
   if (imageId == null) {
     assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
     assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04");
     assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
     assertEquals(defaultTemplate.getLocation().getId(), "1");
     assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
   } else {
     assertEquals(
         defaultTemplate.getImage(),
         this.context.getComputeService().templateBuilder().imageId(imageId).build().getImage());
   }
 }
  @Override
  @BeforeClass(groups = {"integration", "live"})
  public void setupContext() {
    super.setupContext();
    ec2Client = view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi();
    runningTester = retry(new InstanceStateRunning(ec2Client), 600, 5, SECONDS);

    client = ec2Client.getAMIServices();
    if (ebsTemplate != null) {
      Template template = view.getComputeService().templateBuilder().from(ebsTemplate).build();
      regionId = template.getLocation().getId();
      imageId = template.getImage().getProviderId();
      for (Image image : client.describeImagesInRegion(regionId)) {
        if (ebsBackedImageName.equals(image.getName()))
          client.deregisterImageInRegion(regionId, image.getId());
      }
    }
  }
 /**
  * Replaces security groups configured on the given template with one that allows SSH access on
  * port 22 and allows communication on all ports between machines in the same group. Security
  * groups are reused when templates have equal {@link
  * org.jclouds.compute.domain.Template#getLocation locations}.
  *
  * <p>This method is called by Brooklyn when obtaining machines, as part of the {@link
  * JcloudsLocationCustomizer} contract. It should not be called from anywhere else.
  *
  * @param location The Brooklyn location that has called this method while obtaining a machine
  * @param computeService The compute service being used by the location argument to provision a
  *     machine
  * @param template The machine template created by the location argument
  */
 @Override
 public void customize(
     JcloudsLocation location, ComputeService computeService, Template template) {
   if (!computeService.getSecurityGroupExtension().isPresent()) {
     LOG.warn(
         "Security group extension for {} absent; cannot configure security groups in context: {}",
         computeService,
         applicationId);
   } else if (template.getLocation() == null) {
     LOG.warn(
         "No location has been set on {}; cannot configure security groups in context: {}",
         template,
         applicationId);
   } else {
     LOG.info("Configuring security groups on location {} in context {}", location, applicationId);
     setSecurityGroupOnTemplate(
         location, template, computeService.getSecurityGroupExtension().get());
   }
 }
 @Override
 public NodeMetadata createNodeWithGroupEncodedIntoName(
     String group, String name, Template template) {
   Server addedServer = null;
   boolean notStarted = true;
   int numOfRetries = 20;
   GetIpListOptions unassignedIps =
       new GetIpListOptions()
           .onlyUnassigned()
           .inDatacenter(template.getLocation().getId())
           .onlyWithType(IpType.PUBLIC);
   // lock-free consumption of a shared resource: IP address pool
   while (notStarted) { // TODO: replace with Predicate-based thread
     // collision avoidance for simplicity
     Set<Ip> availableIps = client.getIpServices().getIpList(unassignedIps);
     if (availableIps.isEmpty()) throw new RuntimeException("No IPs available on this identity.");
     int ipIndex = new SecureRandom().nextInt(availableIps.size());
     Ip availableIp = Iterables.get(availableIps, ipIndex);
     try {
       addedServer = addServer(name, template, availableIp);
       notStarted = false;
     } catch (Exception e) {
       if (--numOfRetries == 0) Throwables.propagate(e);
       notStarted = true;
     }
   }
   if (template.getOptions().shouldBlockUntilRunning()) {
     serverLatestJobCompleted.apply(addedServer);
     client.getServerServices().power(addedServer.getName(), PowerCommand.START);
     serverLatestJobCompletedShort.apply(addedServer);
     addedServer =
         Iterables.getOnlyElement(
             client.getServerServices().getServersByName(addedServer.getName()));
   }
   Credentials credentials =
       client.getServerServices().getServerCredentialsList().get(addedServer.getName());
   if (credentials != null) credentialStore.put("node#" + addedServer.getId(), credentials);
   else logger.warn("couldn't get credentials for server %s", addedServer.getName());
   return serverToNodeMetadata.apply(addedServer);
 }
 @Test(
     enabled = true,
     dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
 public void testGet() throws Exception {
   Set<? extends NodeMetadata> metadataSet =
       Sets.newHashSet(
           Iterables.filter(
               client.listNodesDetailsMatching(NodePredicates.all()),
               Predicates.and(
                   NodePredicates.withTag(tag), Predicates.not(NodePredicates.TERMINATED))));
   for (NodeMetadata node : nodes) {
     metadataSet.remove(node);
     NodeMetadata metadata = client.getNodeMetadata(node.getId());
     assertEquals(metadata.getProviderId(), node.getProviderId());
     assertEquals(metadata.getTag(), node.getTag());
     assertLocationSameOrChild(metadata.getLocation(), template.getLocation());
     assertEquals(metadata.getImage(), template.getImage());
     assertEquals(metadata.getState(), NodeState.RUNNING);
     assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses());
     assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
   }
   assertNodeZero(metadataSet);
 }
  @Override
  public NodeAndInitialCredentials<Instance> createNodeWithGroupEncodedIntoName(
      String group, String name, Template template) {
    GoogleComputeEngineTemplateOptions options =
        GoogleComputeEngineTemplateOptions.class.cast(template.getOptions());

    checkNotNull(options.getNetworks(), "template options must specify a network");
    checkNotNull(template.getHardware().getUri(), "hardware must have a URI");
    checkNotNull(template.getImage().getUri(), "image URI is null");

    List<AttachDisk> disks = Lists.newArrayList();
    disks.add(AttachDisk.newBootDisk(template.getImage().getUri()));

    Iterator<String> networks = options.getNetworks().iterator();

    URI network = URI.create(networks.next());
    assert !networks.hasNext() : "Error: Options should specify only one network";

    // Add tags from template
    ArrayList<String> tags = new ArrayList<String>(options.getTags());

    // Add tags for firewalls
    FirewallTagNamingConvention naming = firewallTagNamingConvention.get(group);
    List<String> ports = simplifyPorts(options.getInboundPorts());
    if (ports != null) {
      tags.add(naming.name(ports));
    }

    NewInstance newInstance =
        new NewInstance.Builder(
                name,
                template.getHardware().getUri(), // machineType
                network,
                disks)
            .description(group)
            .tags(Tags.create(null, ImmutableList.copyOf(tags)))
            .serviceAccounts(options.serviceAccounts())
            .build();

    // Add metadata from template and for ssh key and image id
    newInstance.metadata().putAll(options.getUserMetadata());

    LoginCredentials credentials = resolveNodeCredentials(template);
    if (options.getPublicKey() != null) {
      newInstance
          .metadata()
          .put(
              "sshKeys",
              format(
                  "%s:%s %s@localhost",
                  credentials.getUser(), options.getPublicKey(), credentials.getUser()));
    }

    String zone = template.getLocation().getId();
    InstanceApi instanceApi = api.instancesInZone(zone);
    Operation create = instanceApi.create(newInstance);

    // We need to see the created instance so that we can access the newly created disk.
    AtomicReference<Instance> instance =
        Atomics.newReference(
            Instance.create( //
                "0000000000000000000", // id can't be null, but isn't available until provisioning
                                       // is done.
                null, // creationTimestamp
                create.targetLink(), // selfLink
                newInstance.name(), // name
                newInstance.description(), // description
                newInstance.tags(), // tags
                newInstance.machineType(), // machineType
                Instance.Status.PROVISIONING, // status
                null, // statusMessage
                create.zone(), // zone
                null, // canIpForward
                null, // networkInterfaces
                null, // disks
                newInstance.metadata(), // metadata
                newInstance.serviceAccounts(), // serviceAccounts
                Scheduling.create(OnHostMaintenance.MIGRATE, true) // scheduling
                ));
    checkState(instanceVisible.apply(instance), "instance %s is not api visible!", instance.get());

    // Add lookup for InstanceToNodeMetadata
    diskToSourceImage.put(instance.get().disks().get(0).source(), template.getImage().getUri());

    return new NodeAndInitialCredentials<Instance>(
        instance.get(), instance.get().selfLink().toString(), credentials);
  }
Exemple #21
0
  public void buildTemplate() {
    IaasProvider iaasInfo = getIaasProvider();
    if (iaasInfo.getComputeService() == null) {
      String msg = "Compute service is null for IaaS provider: " + iaasInfo.getName();
      log.fatal(msg);
      throw new CloudControllerException(msg);
    }

    TemplateBuilder templateBuilder = iaasInfo.getComputeService().templateBuilder();

    // set image id specified
    templateBuilder.imageId(iaasInfo.getImage());

    if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
      Set<? extends Location> locations = iaasInfo.getComputeService().listAssignableLocations();
      for (Location location : locations) {
        if (location.getScope().toString().equalsIgnoreCase(CloudControllerConstants.ZONE_ELEMENT)
            && location
                .getId()
                .equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) {
          templateBuilder.locationId(location.getId());
          log.info(
              "ZONE has been set as "
                  + iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE)
                  + " with id: "
                  + location.getId());
          break;
        }
      }
    }

    if (iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE) != null) {
      // set instance type eg: m1.large
      templateBuilder.hardwareId(iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE));
    }

    // build the Template
    Template template = templateBuilder.build();

    if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
      if (!template
          .getLocation()
          .getId()
          .equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) {
        log.warn(
            "couldn't find assignable ZONE of id :"
                + iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE)
                + " in the IaaS. "
                + "Hence using the default location as "
                + template.getLocation().getScope().toString()
                + " with the id "
                + template.getLocation().getId());
      }
    }

    // if you wish to auto assign IPs, instance spawning call should be
    // blocking, but if you
    // wish to assign IPs manually, it can be non-blocking.
    // is auto-assign-ip mode or manual-assign-ip mode?
    boolean blockUntilRunning =
        Boolean.parseBoolean(iaasInfo.getProperty(CloudControllerConstants.AUTO_ASSIGN_IP));
    template.getOptions().as(TemplateOptions.class).blockUntilRunning(blockUntilRunning);

    // this is required in order to avoid creation of additional security
    // groups by jclouds.
    template.getOptions().as(TemplateOptions.class).inboundPorts();

    // set EC2 specific options

    if (iaasInfo.getProperty(CloudControllerConstants.ASSOCIATE_PUBLIC_IP_ADDRESS) != null) {
      boolean associatePublicIp =
          Boolean.parseBoolean(
              iaasInfo.getProperty(CloudControllerConstants.ASSOCIATE_PUBLIC_IP_ADDRESS));
      if (associatePublicIp) {
        template.getOptions().as(AWSEC2TemplateOptions.class).associatePublicIpAddress();
      }
    }

    if (iaasInfo.getProperty(CloudControllerConstants.SUBNET_ID) != null) {
      template
          .getOptions()
          .as(AWSEC2TemplateOptions.class)
          .subnetId(iaasInfo.getProperty(CloudControllerConstants.SUBNET_ID));
    }

    if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
      template
          .getOptions()
          .as(AWSEC2TemplateOptions.class)
          .placementGroup(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE));
    }

    // security group names
    if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUPS) != null) {
      template
          .getOptions()
          .as(AWSEC2TemplateOptions.class)
          .securityGroups(
              iaasInfo
                  .getProperty(CloudControllerConstants.SECURITY_GROUPS)
                  .split(CloudControllerConstants.ENTRY_SEPARATOR));
    }

    // ability to define tags
    if (iaasInfo.getProperty(CloudControllerConstants.TAGS) != null) {
      template
          .getOptions()
          .as(AWSEC2TemplateOptions.class)
          .tags(
              Arrays.asList(
                  iaasInfo
                      .getProperty(CloudControllerConstants.TAGS)
                      .split(CloudControllerConstants.ENTRY_SEPARATOR)));
    }

    // ability to define tags with Key-value pairs
    Map<String, String> keyValuePairTagsMap = new HashMap<String, String>();

    for (String propertyKey : iaasInfo.getProperties().keySet()) {
      if (propertyKey.startsWith(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX)) {
        keyValuePairTagsMap.put(
            propertyKey.substring(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX.length()),
            iaasInfo.getProperties().get(propertyKey));
        template.getOptions().as(AWSEC2TemplateOptions.class).userMetadata(keyValuePairTagsMap);
      }
    }

    if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS) != null) {
      template
          .getOptions()
          .as(AWSEC2TemplateOptions.class)
          .securityGroupIds(
              iaasInfo
                  .getProperty(CloudControllerConstants.SECURITY_GROUP_IDS)
                  .split(CloudControllerConstants.ENTRY_SEPARATOR));
    }

    if (iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR) != null) {
      template
          .getOptions()
          .as(AWSEC2TemplateOptions.class)
          .keyPair(iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR));
    }

    if (iaasInfo.getNetworkInterfaces() != null) {
      List<String> networks = new ArrayList<String>(iaasInfo.getNetworkInterfaces().length);
      for (NetworkInterface ni : iaasInfo.getNetworkInterfaces()) {
        networks.add(ni.getNetworkUuid());
      }
      template.getOptions().as(AWSEC2TemplateOptions.class).networks(networks);
    }

    // set Template
    iaasInfo.setTemplate(template);
  }
  @Test
  public void testFromSpecWithLoginUser() {

    final Supplier<Set<? extends Location>> locations =
        Suppliers.<Set<? extends Location>>ofInstance(ImmutableSet.<Location>of(region));
    final Supplier<Set<? extends Image>> images =
        Suppliers.<Set<? extends Image>>ofInstance(
            ImmutableSet.<Image>of(
                new ImageBuilder()
                    .id("us-east-2/ami-ffff")
                    .providerId("ami-ffff")
                    .name("Ubuntu 11.04 x64")
                    .description("Ubuntu 11.04 x64")
                    .location(region2)
                    .status(Status.AVAILABLE)
                    .operatingSystem(
                        OperatingSystem.builder()
                            .name("Ubuntu 11.04 x64")
                            .description("Ubuntu 11.04 x64")
                            .is64Bit(true)
                            .version("11.04")
                            .family(OsFamily.UBUNTU)
                            .build())
                    .build()));

    final Supplier<Set<? extends Hardware>> hardwares =
        Suppliers.<Set<? extends Hardware>>ofInstance(
            ImmutableSet.<Hardware>of(
                new HardwareBuilder()
                    .ids("m1.small")
                    .ram(512)
                    .processors(ImmutableList.of(new Processor(1, 1.0)))
                    .volumes(ImmutableList.<Volume>of(new VolumeImpl((float) 5, true, true)))
                    .build()));

    final Provider<TemplateOptions> optionsProvider =
        new Provider<TemplateOptions>() {

          @Override
          public TemplateOptions get() {
            return new TemplateOptions();
          }
        };
    Provider<TemplateBuilder> templateBuilderProvider =
        new Provider<TemplateBuilder>() {

          @Override
          public TemplateBuilder get() {
            return createTemplateBuilder(
                null, locations, images, hardwares, region, optionsProvider, this);
          }
        };

    TemplateBuilder templateBuilder =
        templateBuilderProvider
            .get()
            .from(
                "hardwareId=m1.small,imageId=us-east-2/ami-ffff,loginUser=user:Password01,authenticateSudo=true");

    assertEquals(templateBuilder.toString(), "{imageId=us-east-2/ami-ffff, hardwareId=m1.small}");

    Template template = templateBuilder.build();
    assertEquals(template.getLocation().getId(), "us-east-2");
    assertEquals(template.getOptions().getLoginUser(), "user");
    assertEquals(template.getOptions().getLoginPassword(), "Password01");
    assertEquals(template.getOptions().getLoginPrivateKey(), null);
    assertEquals(template.getOptions().shouldAuthenticateSudo(), Boolean.TRUE);
  }