public AtomicReference<NodeMetadata> apply(AtomicReference<NodeAndNovaTemplateOptions> input) {
checkState(nodeRunning.apply(input.get().getNodeMetadata()), "node never achieved state running %s", input.get().getNodeMetadata());
NodeMetadata node = input.get().getNodeMetadata().get();
// node's location is a host
String regionId = node.getLocation().getParent().getId();
FloatingIPApi floatingIpApi = novaApi.getFloatingIPApi(regionId).get();
Optional<Set<String>> poolNames = input.get().getNovaTemplateOptions().get().getFloatingIpPoolNames();
Optional<FloatingIP> ip = allocateFloatingIPForNode(floatingIpApi, poolNames, node.getId());
if (!ip.isPresent()) {
throw new InsufficientResourcesException("Failed to allocate a FloatingIP for node(" + node.getId() + ")");
}
logger.debug(">> adding floatingIp(%s) to node(%s)", ip.get().getIp(), node.getId());
floatingIpApi.addToServer(ip.get().getIp(), node.getProviderId());
input.get().getNodeMetadata().set(NodeMetadataBuilder.fromNodeMetadata(node).publicAddresses(ImmutableSet.of(ip.get().getIp())).build());
floatingIpCache.invalidate(RegionAndId.fromSlashEncoded(node.getId()));
return input.get().getNodeMetadata();
}