@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;
  }
  @Override
  public List<String> associateAddresses(NodeMetadata node) {

    assertNotNull(node, "Node cannot be null");

    if (null == neutronApi || null == portApi || null == floatingIPApi) {
      buildNeutronApi();
    }

    // internal network uuid to floating networks map, as defined in cartridge definition
    Map<String, List<FloatingNetwork>> networkUuidToFloatingNetworksMap =
        getNetworkUuidToFloatingNetworksMap(iaasProvider.getNetworkInterfaces());

    // private IP to floating networks map, as defined in cartridge definition
    Map<String, List<FloatingNetwork>> fixedIPToFloatingNetworksMap =
        getFixedIPToFloatingNetworksMap(iaasProvider.getNetworkInterfaces());

    // list of IPs allocated to this node
    List<String> associatedFloatingIPs = new ArrayList<String>();

    // wait until node gets private IPs
    while (node.getPrivateAddresses() == null) {
      CloudControllerUtil.sleep(1000);
    }

    // loop through all the fixed IPs of this node
    // and see whether we need to assign floating IP to each according to the cartridge deployment
    for (String privateIPOfTheNode : node.getPrivateAddresses()) {
      Port portOfTheFixedIP = getPortByFixedIP(privateIPOfTheNode);
      if (null == portOfTheFixedIP) {
        // we can't assign floating IP if port is null
        // it can't happen, a fixed/private IP can't live without a port
        // but doing a null check to be on the safe side
        if (log.isDebugEnabled()) {
          String msg = String.format("Port not found for fixed IP %s", privateIPOfTheNode);
          log.debug(msg);
        }
        continue;
      }
      // get list of floating networks associated with each network interfaces (refer cartridge
      // definition)
      List<FloatingNetwork> floatingNetworks =
          networkUuidToFloatingNetworksMap.get(portOfTheFixedIP.getNetworkId());
      // if no floating networks is defined for a network interface, no need to assign any floating
      // IPs, skip the current iteration
      if (null == floatingNetworks || floatingNetworks.isEmpty()) {
        // since no floating networks found in networkUuidToFloatingNetworksMap,
        // we will search in fixedIPToFloatingNetworksMap
        floatingNetworks = fixedIPToFloatingNetworksMap.get(privateIPOfTheNode);
        if (null == floatingNetworks || floatingNetworks.isEmpty()) {
          if (log.isDebugEnabled()) {
            String msg =
                String.format(
                    "No floating networks defined for the network interface %s",
                    portOfTheFixedIP.getNetworkId());
            log.debug(msg);
          }
        }
        continue;
      }
      // if floating networks defined for a network interface, assign one floating IP from each
      // floating network
      for (FloatingNetwork floatingNetwork : floatingNetworks) {
        FloatingIP allocatedFloatingIP = null;
        if (floatingNetwork.getNetworkUuid() != null
            && !floatingNetwork.getNetworkUuid().isEmpty()) {
          allocatedFloatingIP =
              assignFloatingIP(portOfTheFixedIP, floatingNetwork.getNetworkUuid());
        } else if (floatingNetwork.getFloatingIP() != null
            && !floatingNetwork.getFloatingIP().isEmpty()) {
          allocatedFloatingIP =
              assignPredefinedFloatingIP(portOfTheFixedIP, floatingNetwork.getFloatingIP());
        } else {
          String msg =
              String.format(
                  "Neither floating network uuid or floating IP defined for the floating network %s",
                  floatingNetwork.getName());
          log.error(msg);
          throw new CloudControllerException(msg);
        }

        String allocatedFloatingIPNullMsg =
            String.format(
                "Error occured while assigning floating IP. "
                    + "Please check whether the floating network %s can be reached from the fixed IP range",
                floatingNetwork.getNetworkUuid());
        assertNotNull(allocatedFloatingIP, allocatedFloatingIPNullMsg);

        String allocatedFloatingIPAddressNullOrEmptyMsg =
            String.format(
                "Error occured while assigning floating IP. "
                    + "Please check whether the floating network %s can be reached from the fixed IP range",
                floatingNetwork.getNetworkUuid());
        assertNotNullAndNotEmpty(
            allocatedFloatingIP.getFloatingIpAddress(), allocatedFloatingIPAddressNullOrEmptyMsg);

        associatedFloatingIPs.add(allocatedFloatingIP.getFloatingIpAddress());
      }
    }
    return associatedFloatingIPs;
  }
  @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;
    }
  }
示例#4
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;
  }