NodeMetadata node = input.get();
// node's location is a host
String zoneId = node.getLocation().getParent().getId();
FloatingIPApi floatingIpApi = novaApi.getFloatingIPExtensionForZone(zoneId).get();
FloatingIP ip = null;
try {
logger.debug(">> allocating or reassigning floating ip for node(%s)", node.getId());
ip = floatingIpApi.create();
} catch (InsufficientResourcesException e) {
logger.trace("<< [%s] allocating a new floating ip for node(%s)", e.getMessage(), node.getId());
logger.trace(">> searching for existing, unassigned floating ip for node(%s)", node.getId());
ArrayList<FloatingIP> unassignedIps = Lists.newArrayList(Iterables.filter(floatingIpApi.list(),
new Predicate<FloatingIP>() {
@Override
public boolean apply(FloatingIP arg0) {
return arg0.getFixedIp() == null;
}
}));
// try to prevent multiple parallel launches from choosing the same ip.
Collections.shuffle(unassignedIps);
ip = Iterables.getLast(unassignedIps);
}
logger.debug(">> adding floatingIp(%s) to node(%s)", ip.getIp(), node.getId());
floatingIpApi.addToServer(ip.getIp(), node.getProviderId());
input.set(NodeMetadataBuilder.fromNodeMetadata(node).publicAddresses(ImmutableSet.of(ip.getIp())).build());
floatingIpCache.invalidate(ZoneAndId.fromSlashEncoded(node.getId()));
return input;
}