cloudHost.createInstance = false;
cloudHost.instance = backendItem;
addChild(cloudHost);
}
final SocketAddressPoolAssignment assignPublicAddress;
{
assignPublicAddress = cloudHost.addChild(SocketAddressPoolAssignment.class);
assignPublicAddress.holder = backendItem.getKey();
if (Objects.equal(transport, Transport.Ipv6)) {
assignPublicAddress.poolProvider = new OpsProvider<ResourcePool<InetSocketAddress>>() {
@Override
public ResourcePool<InetSocketAddress> get() throws OpsException {
final ResourcePool<AddressModel> pool = directCloudHelpers.getAddressPool6().get();
return new AssignPortToAddressPool(pool, publicPort);
}
};
} else {
List<Integer> publicPortCluster = this.publicPortCluster;
if (publicPortCluster == null) {
publicPortCluster = Lists.newArrayList();
publicPortCluster.add(publicPort);
}
if (!publicPortCluster.contains(publicPort)) {
throw new OpsException("Port set specified, but public port not in the set");
}
assignPublicAddress.poolProvider = directCloudHelpers.getPublicAddressPool4(publicPort, publicPortCluster);
}
}
if (Objects.equal(transport, Transport.Ipv6)) {
// TODO: Do we need separate frontend / backend ports really?
if (this.publicPort != this.backendPort) {
throw new UnsupportedOperationException();
}
} else {
for (Protocol protocol : Protocol.TcpAndUdp()) {
IptablesForwardPort forward = injected(IptablesForwardPort.class);
forward.publicAddress = assignPublicAddress;
forward.ruleKey = protocol.name() + "-" + uuid;
forward.protocol = protocol;
forward.privateAddress = new OpsProvider<String>() {
@Override
public String get() throws OpsException {
// Refresh item to pick up new tags
backendItem = platformLayerClient.getItem(backendItem.getKey(), DirectInstance.class);
PlatformLayerCloudMachine instanceMachine = (PlatformLayerCloudMachine) instanceHelpers
.getMachine(backendItem);
DirectInstance instance = (DirectInstance) instanceMachine.getInstance();
List<InetAddress> addresses = Tag.NETWORK_ADDRESS.find(instance);
InetAddress address = InetAddressChooser.preferIpv4().choose(addresses);
if (address == null) {
throw new IllegalStateException();
}
if (InetAddressUtils.isIpv6(address)) {
// We can't NAT IPV4 -> IPV6 (I think)
throw new IllegalStateException();
}
return address.getHostAddress();
}
};
forward.privatePort = backendPort;
cloudHost.addChild(forward);
}
}
{
OpsProvider<TagChanges> tagChanges = new OpsProvider<TagChanges>() {
@Override
public TagChanges get() {
TagChanges tagChanges = new TagChanges();
InetSocketAddress socketAddress = assignPublicAddress.get();
if (socketAddress == null) {
return null;
}
if (socketAddress.getPort() != publicPort) {