Ejemplo n.º 1
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.º 2
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);
  }