Ejemplo n.º 1
0
  @Override
  public boolean isValidZone(String region, String zone) throws InvalidZoneException {
    IaasProvider iaasInfo = getIaasProvider();
    if (zone == null || iaasInfo == null) {
      String msg = "Zone or IaaSProvider is null: zone: " + zone + " - IaaSProvider: " + iaasInfo;
      log.error(msg);
      throw new InvalidZoneException(msg);
    }
    ComputeServiceContext context = iaasInfo.getComputeService().getContext();
    AvailabilityZoneAndRegionApi zoneRegionApi =
        context.unwrapApi(AWSEC2Api.class).getAvailabilityZoneAndRegionApiForRegion(region).get();

    Set<AvailabilityZoneInfo> availabilityZones =
        zoneRegionApi.describeAvailabilityZonesInRegion(region);
    for (AvailabilityZoneInfo zoneInfo : availabilityZones) {
      String configuredZone = zoneInfo.getZone();
      if (zone.equalsIgnoreCase(configuredZone)) {
        if (log.isDebugEnabled()) {
          log.debug("Found a matching zone: " + zone);
        }
        return true;
      }
    }

    String msg =
        "Invalid zone: "
            + zone
            + " in the region: "
            + region
            + " and of the iaas: "
            + iaasInfo.getType();
    log.error(msg);
    throw new InvalidZoneException(msg);
  }
Ejemplo n.º 2
0
 @Override
 public void deleteVolume(String volumeId) {
   IaasProvider iaasInfo = getIaasProvider();
   ComputeServiceContext context = iaasInfo.getComputeService().getContext();
   String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
   if (region == null) {
     log.fatal(
         "Cannot delete the volume [id]: "
             + volumeId
             + " of the [region] : "
             + region
             + " of Iaas : "
             + iaasInfo);
     return;
   }
   ElasticBlockStoreApi blockStoreApi =
       context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
   blockStoreApi.deleteVolumeInRegion(region, volumeId);
   log.info(
       "Deletion of Volume [id]: "
           + volumeId
           + " was successful. [region] : "
           + region
           + " of Iaas : "
           + iaasInfo);
 }
Ejemplo n.º 3
0
  @Override
  public String createVolume(int sizeGB, String snapshotId) {
    IaasProvider iaasInfo = getIaasProvider();

    ComputeServiceContext context = iaasInfo.getComputeService().getContext();

    String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
    String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);

    if (region == null || zone == null) {
      log.fatal(
          "Cannot create a new volume in the [region] : "
              + region
              + ", [zone] : "
              + zone
              + " of Iaas : "
              + iaasInfo);
      return null;
    }

    ElasticBlockStoreApi blockStoreApi =
        context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();

    Volume volume;
    if (StringUtils.isEmpty(snapshotId)) {
      if (log.isDebugEnabled()) {
        log.info("Creating a volume in the zone " + zone);
      }
      volume = blockStoreApi.createVolumeInAvailabilityZone(zone, sizeGB);
    } else {
      if (log.isDebugEnabled()) {
        log.info("Creating a volume in the zone " + zone + " from the shanpshot " + snapshotId);
      }
      volume = blockStoreApi.createVolumeFromSnapshotInAvailabilityZone(zone, snapshotId);
    }

    if (volume == null) {
      log.fatal(
          "Volume creation was unsuccessful. [region] : "
              + region
              + ", [zone] : "
              + zone
              + " of Iaas : "
              + iaasInfo);
      return null;
    }

    log.info(
        "Successfully created a new volume [id]: "
            + volume.getId()
            + " in [region] : "
            + region
            + ", [zone] : "
            + zone
            + " of Iaas : "
            + iaasInfo);
    return volume.getId();
  }
Ejemplo n.º 4
0
  @Override
  public synchronized void releaseAddress(String ip) {

    IaasProvider iaasInfo = getIaasProvider();

    ComputeServiceContext context = iaasInfo.getComputeService().getContext();
    ElasticIPAddressApi elasticIPAddressApi =
        context.unwrapApi(AWSEC2Api.class).getElasticIPAddressApi().get();
    String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);

    elasticIPAddressApi.disassociateAddressInRegion(region, ip);
    elasticIPAddressApi.releaseAddressInRegion(region, ip);
  }
Ejemplo n.º 5
0
  @Override
  public void releaseAddress(String ip) {

    ComputeServiceContext context = iaasProvider.getComputeService().getContext();
    String region = ComputeServiceBuilderUtil.extractRegion(iaasProvider);

    NovaApi novaApi = context.unwrapApi(NovaApi.class);
    FloatingIPApi floatingIPApi = novaApi.getFloatingIPExtensionForZone(region).get();

    for (FloatingIP floatingIP : floatingIPApi.list()) {
      if (floatingIP.getIp().equals(ip)) {
        floatingIPApi.delete(floatingIP.getId());
        break;
      }
    }
  }
Ejemplo n.º 6
0
  @Override
  public void detachVolume(String instanceId, String volumeId) {
    IaasProvider iaasInfo = getIaasProvider();
    ComputeServiceContext context = iaasInfo.getComputeService().getContext();
    String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
    if (region == null) {
      log.fatal(
          "Cannot detach the volume [id]: "
              + volumeId
              + " from the instance [id]: "
              + instanceId
              + " of the [region] : "
              + region
              + " of Iaas : "
              + iaasInfo);
      return;
    }

    ElasticBlockStoreApi blockStoreApi =
        context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
    Set<Volume> volumeDescriptions = blockStoreApi.describeVolumesInRegion(region, volumeId);
    Iterator<Volume> it = volumeDescriptions.iterator();

    while (it.hasNext()) {
      Volume.Status status = it.next().getStatus();
      if (status == Volume.Status.AVAILABLE) {
        log.warn(
            String.format(
                "Volume %s is already in AVAILABLE state. Volume seems to be detached somehow",
                volumeId));
        return;
      }
    }
    blockStoreApi.detachVolumeInRegion(
        region, volumeId, true, DetachVolumeOptions.Builder.fromInstance(instanceId));

    log.info(
        "Detachment of Volume [id]: "
            + volumeId
            + " from instance [id]: "
            + instanceId
            + " was successful. [region] : "
            + region
            + " of Iaas : "
            + iaasInfo);
  }
Ejemplo n.º 7
0
 @Override
 public synchronized boolean createKeyPairFromPublicKey(
     String region, String keyPairName, String publicKey) {
   IaasProvider iaasInfo = getIaasProvider();
   String ec2Msg = " ec2. Region: " + region + " - Key Pair Name: ";
   ComputeServiceContext context = iaasInfo.getComputeService().getContext();
   AWSKeyPairApi keyPairApi =
       context.unwrapApi(AWSEC2Api.class).getKeyPairApiForRegion(region).get();
   KeyPair keyPair = keyPairApi.importKeyPairInRegion(region, keyPairName, publicKey);
   if (keyPair != null) {
     iaasInfo
         .getTemplate()
         .getOptions()
         .as(AWSEC2TemplateOptions.class)
         .keyPair(keyPair.getKeyName());
     log.info(SUCCESSFUL_LOG_LINE + ec2Msg + keyPair.getKeyName());
     return true;
   }
   log.error(FAILED_LOG_LINE + ec2Msg);
   return false;
 }
Ejemplo n.º 8
0
  @Override
  public boolean isValidRegion(String region) throws InvalidRegionException {
    IaasProvider iaasInfo = getIaasProvider();
    if (region == null || iaasInfo == null) {
      String msg =
          "Region or IaaSProvider is null: region: " + region + " - IaaSProvider: " + iaasInfo;
      log.error(msg);
      throw new InvalidRegionException(msg);
    }

    ComputeServiceContext context = iaasInfo.getComputeService().getContext();
    Set<String> regions = context.unwrapApi(AWSEC2Api.class).getConfiguredRegions();
    for (String configuredRegion : regions) {
      if (region.equalsIgnoreCase(configuredRegion)) {
        if (log.isDebugEnabled()) {
          log.debug("Found a matching region: " + region);
        }
        return true;
      }
    }
    String msg = "Invalid region: " + region + " in the iaas: " + iaasInfo.getType();
    log.error(msg);
    throw new InvalidRegionException(msg);
  }
Ejemplo n.º 9
0
  @Override
  public List<String> associateAddresses(NodeMetadata node) {

    ComputeServiceContext context = iaasProvider.getComputeService().getContext();
    String region = ComputeServiceBuilderUtil.extractRegion(iaasProvider);

    if (StringUtils.isEmpty(region)) {
      throw new RuntimeException(
          "Could not find region in iaas provider: " + iaasProvider.getName());
    }

    NovaApi novaApi = context.unwrapApi(NovaApi.class);
    FloatingIPApi floatingIPApi = novaApi.getFloatingIPExtensionForZone(region).get();

    String ip = null;
    // first try to find an unassigned IP.
    FluentIterable<FloatingIP> floatingIPs = floatingIPApi.list();
    ArrayList<FloatingIP> unassignedIps =
        Lists.newArrayList(
            Iterables.filter(
                floatingIPs,
                new Predicate<FloatingIP>() {
                  @Override
                  public boolean apply(FloatingIP floatingIP) {
                    return floatingIP.getInstanceId() == null;
                  }
                }));

    if (!unassignedIps.isEmpty()) {
      // try to prevent multiple parallel launches from choosing the same ip.
      Collections.shuffle(unassignedIps);
      ip = Iterables.getLast(unassignedIps).getIp();
    }

    // if no unassigned IP is available, we'll try to allocate an IP.
    if (StringUtils.isEmpty(ip)) {
      String floatingIpPool =
          iaasProvider.getProperty(CloudControllerConstants.DEFAULT_FLOATING_IP_POOL);
      FloatingIP allocatedFloatingIP;
      if (StringUtils.isEmpty(floatingIpPool)) {
        allocatedFloatingIP = floatingIPApi.create();
      } else {
        log.debug(
            String.format(
                "Trying to allocate a floating IP address from IP pool %s", floatingIpPool));
        allocatedFloatingIP = floatingIPApi.allocateFromPool(floatingIpPool);
      }
      if (allocatedFloatingIP == null) {
        String msg =
            String.format(
                "Floating IP API did not return a floating IP address from IP pool %s",
                floatingIpPool);
        log.error(msg);
        throw new CloudControllerException(msg);
      }
      ip = allocatedFloatingIP.getIp();
    }

    // wait till the fixed IP address gets assigned - this is needed before
    // we associate a public IP
    log.info(
        String.format(
            "Waiting for private IP addresses get allocated: [node-id] %s", node.getId()));
    while (node.getPrivateAddresses() == null) {
      CloudControllerUtil.sleep(1000);
    }
    log.info(String.format("Private IP addresses allocated: %s", node.getPrivateAddresses()));

    if ((node.getPublicAddresses() != null) && (node.getPublicAddresses().iterator().hasNext())) {
      log.info(
          "Public IP address "
              + node.getPublicAddresses().iterator().next()
              + " is already allocated to the instance: [node-id]  "
              + node.getId());
      return null;
    }

    int retries = 0;
    int retryCount = Integer.getInteger("stratos.public.ip.association.retry.count", 5);
    while ((retries < retryCount) && (!associateIp(floatingIPApi, ip, node.getProviderId()))) {
      // wait for 5s
      CloudControllerUtil.sleep(5000);
      retries++;
    }

    log.info(
        String.format(
            "Successfully associated an IP address: [node-id] %s [ip] %s", node.getId(), ip));

    List<String> allocatedIPAddresses = new ArrayList<String>();
    allocatedIPAddresses.add(ip);
    return allocatedIPAddresses;
  }
Ejemplo n.º 10
0
  @Override
  public String associatePredefinedAddress(NodeMetadata node, String ip) {
    if (log.isDebugEnabled()) {
      log.debug(
          String.format(
              "Trying to associate predefined IP address: [node-id] %s [ip] %s", node.getId(), ip));
    }

    ComputeServiceContext context = iaasProvider.getComputeService().getContext();
    String region = ComputeServiceBuilderUtil.extractRegion(iaasProvider);

    FloatingIPApi floatingIPApi =
        context.unwrapApi(NovaApi.class).getFloatingIPExtensionForZone(region).get();

    // get the list of all unassigned IP.
    ArrayList<FloatingIP> unassignedFloatingIPs =
        Lists.newArrayList(
            Iterables.filter(
                floatingIPApi.list(),
                new Predicate<FloatingIP>() {
                  @Override
                  public boolean apply(FloatingIP floatingIP) {
                    return StringUtils.isEmpty(floatingIP.getFixedIp());
                  }
                }));

    boolean isAvailable = false;
    for (FloatingIP floatingIP : unassignedFloatingIPs) {
      if (log.isDebugEnabled()) {
        log.debug(
            "OpenstackNovaIaas:associatePredefinedAddress:iterating over available floatingip:"
                + floatingIP);
      }
      if (ip.equals(floatingIP.getIp())) {
        if (log.isDebugEnabled()) {
          log.debug(
              String.format(
                  "OpenstackNovaIaas:associatePredefinedAddress:floating ip in use:%s /ip:%s",
                  floatingIP, ip));
        }
        isAvailable = true;
        break;
      }
    }

    if (isAvailable) {
      // assign ip
      if (log.isDebugEnabled()) {
        log.debug("OpenstackNovaIaas:associatePredefinedAddress:assign floating ip:" + ip);
      }
      // exercise same code as in associateAddress()
      // wait till the fixed IP address gets assigned - this is needed before
      // we associate a public IP

      while (node.getPrivateAddresses() == null) {
        CloudControllerUtil.sleep(1000);
      }

      int retries = 0;
      int retryCount = Integer.getInteger("stratos.public.ip.association.retry.count", 5);
      while (retries < retryCount && !associateIp(floatingIPApi, ip, node.getProviderId())) {
        // wait for 5s
        CloudControllerUtil.sleep(5000);
        retries++;
      }

      NodeMetadataBuilder.fromNodeMetadata(node).publicAddresses(ImmutableSet.of(ip)).build();
      log.info(
          String.format(
              "Successfully associated predefined IP address: [node-id] %s [ip] %s ",
              node.getId(), ip));
      return ip;
    } else {
      log.warn(
          String.format(
              "Could not associate predefined IP address: [node-id] %s [ip] %s ",
              node.getId(), ip));
      return null;
    }
  }
Ejemplo n.º 11
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);
  }
Ejemplo n.º 12
0
  @Override
  public String attachVolume(String instanceId, String volumeId, String deviceName) {
    IaasProvider iaasInfo = getIaasProvider();
    ComputeServiceContext context = iaasInfo.getComputeService().getContext();
    String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
    String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
    String device = deviceName == null ? "/dev/sdh" : deviceName;

    if (region == null || zone == null) {
      log.fatal(
          "Cannot attach the volume [id]: "
              + volumeId
              + " in the [region] : "
              + region
              + ", [zone] : "
              + zone
              + " of Iaas : "
              + iaasInfo);
      return null;
    }

    ElasticBlockStoreApi blockStoreApi =
        context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
    Volume.Status volumeStatus = this.getVolumeStatus(blockStoreApi, region, volumeId);

    if (log.isDebugEnabled()) {
      log.debug("Volume " + volumeId + " is in state " + volumeStatus);
    }

    while (volumeStatus != Volume.Status.AVAILABLE) {
      try {
        // TODO Use a proper mechanism to wait till volume becomes available.
        Thread.sleep(1000);
        volumeStatus = this.getVolumeStatus(blockStoreApi, region, volumeId);
        if (log.isDebugEnabled()) {
          log.debug(
              "Volume " + volumeId + " is still NOT in AVAILABLE. Current State=" + volumeStatus);
        }
      } catch (InterruptedException e) {
        // Ignoring the exception
      }
    }
    if (log.isDebugEnabled()) {
      log.debug("Volume " + volumeId + " became  AVAILABLE");
    }

    Attachment attachment =
        blockStoreApi.attachVolumeInRegion(region, volumeId, instanceId, device);

    if (attachment == null) {
      log.fatal(
          "Volume [id]: "
              + volumeId
              + " attachment for instance [id]: "
              + instanceId
              + " was unsuccessful. [region] : "
              + region
              + ", [zone] : "
              + zone
              + " of Iaas : "
              + iaasInfo);
      return null;
    }

    log.info(
        "Volume [id]: "
            + volumeId
            + " attachment for instance [id]: "
            + instanceId
            + " was successful [status]: "
            + attachment.getStatus().value()
            + ". [region] : "
            + region
            + ", [zone] : "
            + zone
            + " of Iaas : "
            + iaasInfo);
    return attachment.getStatus().value();
  }
Ejemplo n.º 13
0
  @Override
  public synchronized List<String> associateAddresses(NodeMetadata node) {
    IaasProvider iaasInfo = getIaasProvider();
    ComputeServiceContext context = iaasInfo.getComputeService().getContext();
    ElasticIPAddressApi elasticIPAddressApi =
        context.unwrapApi(AWSEC2Api.class).getElasticIPAddressApi().get();
    String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
    String ip = null;

    // first try to find an unassigned IP.
    ArrayList<PublicIpInstanceIdPair> unassignedIps =
        Lists.newArrayList(
            Iterables.filter(
                elasticIPAddressApi.describeAddressesInRegion(region),
                new Predicate<PublicIpInstanceIdPair>() {

                  @Override
                  public boolean apply(PublicIpInstanceIdPair arg0) {
                    return arg0.getInstanceId() == null;
                  }
                }));

    if (!unassignedIps.isEmpty()) {
      // try to prevent multiple parallel launches from choosing the same
      // ip.
      Collections.shuffle(unassignedIps);
      ip = Iterables.getLast(unassignedIps).getPublicIp();
    }

    // if no unassigned IP is available, we'll try to allocate an IP.
    if (ip == null || ip.isEmpty()) {
      try {
        ip = elasticIPAddressApi.allocateAddressInRegion(region);
        log.info("Allocated ip [" + ip + "]");

      } catch (Exception e) {
        String msg = "Failed to allocate an IP address. All IP addresses are in use.";
        log.error(msg, e);
        throw new CloudControllerException(msg, e);
      }
    }

    String id = node.getProviderId();

    // wait till the fixed IP address gets assigned - this is needed before
    // we associate a
    // public IP

    while (node.getPrivateAddresses() == null) {
      CloudControllerUtil.sleep(1000);
    }

    int retries = 0;
    while (retries < 12 && !associatePublicIp(elasticIPAddressApi, region, ip, id)) {

      // wait for 5s
      CloudControllerUtil.sleep(5000);
      retries++;
    }

    log.debug("Successfully associated an IP address " + ip + " for node with id: " + node.getId());

    List<String> associatedIPs = new ArrayList<String>();
    associatedIPs.add(ip);
    return associatedIPs;
  }