// Allocates new elastic IP addresses.
  public static Instance allocateElasticIP(Instance ins) {
    // allocate
    AllocateAddressResult elasticResult = ec2.allocateAddress();
    String elasticIp = elasticResult.getPublicIp();
    System.out.println("New elastic IP: " + elasticIp);

    // associate
    AssociateAddressRequest aar = new AssociateAddressRequest();
    aar.setInstanceId(ins.getInstanceId());
    aar.setPublicIp(elasticIp);
    ec2.associateAddress(aar);

    ins = updatedInstance(ins);

    return ins;
  }
Example #2
0
  /**
   * Checks if an EIP is bound and optionally binds the EIP.
   *
   * <p>The list of EIPs are arranged with the EIPs allocated in the zone first followed by other
   * EIPs.
   *
   * <p>If an EIP is already bound to this instance this method simply returns. Otherwise, this
   * method tries to find an unused EIP based on information from AWS. If it cannot find any unused
   * EIP this method, it will be retried for a specified interval.
   *
   * <p>One of the following scenarios can happen here :
   *
   * <p>1) If the instance is already bound to an EIP as deemed by AWS, no action is taken. 2) If an
   * EIP is already bound to another instance as deemed by AWS, that EIP is skipped. 3) If an EIP is
   * not already bound to an instance and if this instance is not bound to an EIP, then the EIP is
   * bound to this instance.
   */
  public void bindEIP() {
    InstanceInfo myInfo = applicationInfoManager.getInfo();
    String myInstanceId = ((AmazonInfo) myInfo.getDataCenterInfo()).get(MetaDataKey.instanceId);
    String myZone = ((AmazonInfo) myInfo.getDataCenterInfo()).get(MetaDataKey.availabilityZone);

    Collection<String> candidateEIPs = getCandidateEIPs(myInstanceId, myZone);

    AmazonEC2 ec2Service = getEC2Service();
    boolean isMyinstanceAssociatedWithEIP = false;
    Address selectedEIP = null;

    for (String eipEntry : candidateEIPs) {
      try {
        String associatedInstanceId;

        // Check with AWS, if this EIP is already been used by another instance
        DescribeAddressesRequest describeAddressRequest =
            new DescribeAddressesRequest().withPublicIps(eipEntry);
        DescribeAddressesResult result = ec2Service.describeAddresses(describeAddressRequest);
        if ((result.getAddresses() != null) && (!result.getAddresses().isEmpty())) {
          Address eipAddress = result.getAddresses().get(0);
          associatedInstanceId = eipAddress.getInstanceId();
          // This EIP is not used by any other instance, hence mark it for selection if it is not
          // already marked.
          if (((associatedInstanceId == null) || (associatedInstanceId.isEmpty()))) {
            if (selectedEIP == null) {
              selectedEIP = eipAddress;
            }
          } else if (isMyinstanceAssociatedWithEIP = (associatedInstanceId.equals(myInstanceId))) {
            // This EIP is associated with an instance, check if this is the same as the current
            // instance.
            // If it is the same, stop searching for an EIP as this instance is already associated
            // with an
            // EIP
            selectedEIP = eipAddress;
            break;
          } else {
            // The EIP is used by some other instance, hence skip it
            logger.warn(
                "The selected EIP {} is associated with another instance {} according to AWS,"
                    + " hence skipping this",
                eipEntry,
                associatedInstanceId);
          }
        }
      } catch (Throwable t) {
        logger.error("Failed to bind elastic IP: {} to {}", eipEntry, myInstanceId, t);
      }
    }
    if (null != selectedEIP) {
      String publicIp = selectedEIP.getPublicIp();
      // Only bind if the EIP is not already associated
      if (!isMyinstanceAssociatedWithEIP) {

        AssociateAddressRequest associateAddressRequest =
            new AssociateAddressRequest().withInstanceId(myInstanceId);

        String domain = selectedEIP.getDomain();
        if ("vpc".equals(domain)) {
          associateAddressRequest.setAllocationId(selectedEIP.getAllocationId());
        } else {
          associateAddressRequest.setPublicIp(publicIp);
        }

        ec2Service.associateAddress(associateAddressRequest);
        logger.info(
            "\n\n\nAssociated {} running in zone: {} to elastic IP: {}",
            myInstanceId,
            myZone,
            publicIp);
      }
      logger.info(
          "My instance {} seems to be already associated with the EIP {}", myInstanceId, publicIp);
    } else {
      logger.info(
          "No EIP is free to be associated with this instance. Candidate EIPs are: {}",
          candidateEIPs);
    }
  }