docker: get container’s IPs from all networks

This commit is contained in:
Aled Sage 2016-06-13 14:03:26 +01:00 committed by Andrea Turli
parent 91339b200e
commit fc88756d5a
4 changed files with 97 additions and 9 deletions

View File

@ -31,6 +31,7 @@ import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.functions.GroupNamingConvention;
import org.jclouds.docker.domain.Container;
import org.jclouds.docker.domain.NetworkSettings;
import org.jclouds.docker.domain.State;
import org.jclouds.domain.Location;
import org.jclouds.providers.ProviderMetadata;
@ -38,6 +39,7 @@ import org.jclouds.providers.ProviderMetadata;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.Singleton;
@ -106,8 +108,24 @@ public class ContainerToNodeMetadata implements Function<Container, NodeMetadata
}
private Iterable<String> getPrivateIpAddresses(Container container) {
// A container can be attached to multiple networks. It can therefore have multiple private
// IPs. The NetworkSettings.ipAddress might in fact be blank, with the only IP being on
// network objects.
if (container.networkSettings() == null) return ImmutableList.of();
return ImmutableList.of(container.networkSettings().ipAddress());
ImmutableSet.Builder<String> builder = ImmutableSet.<String>builder();
NetworkSettings settings = container.networkSettings();
if (settings.ipAddress() != null && settings.ipAddress().length() > 0) {
builder.add(settings.ipAddress());
}
if (settings.networks() != null) {
for (Map.Entry<String, NetworkSettings.Details> entry : settings.networks().entrySet()) {
String ipAddress = entry.getValue().ipAddress();
if (ipAddress != null && ipAddress.length() > 0) {
builder.add(ipAddress);
}
}
}
return builder.build();
}
private List<String> getPublicIpAddresses(Container container) {

View File

@ -56,8 +56,32 @@ public abstract class NetworkSettings {
@SerializedNames({ "EndpointID", "Gateway", "IPAddress", "IPPrefixLen", "IPv6Gateway", "GlobalIPv6Address", "GlobalIPv6PrefixLen", "MacAddress" })
public static Details create(String endpointId, String gateway, String ipAddress, int ipPrefixLen, String ipv6Gateway, String globalIPv6Address,
int globalIPv6PrefixLen, String macAddress) {
return new AutoValue_NetworkSettings_Details(endpointId, gateway, ipAddress, ipPrefixLen, ipv6Gateway, globalIPv6Address, globalIPv6PrefixLen,
macAddress);
return builder().endpoint(endpointId).gateway(gateway).ipAddress(ipAddress).ipPrefixLen(ipPrefixLen)
.ipv6Gateway(ipv6Gateway).globalIPv6Address(globalIPv6Address)
.globalIPv6PrefixLen(globalIPv6PrefixLen).macAddress(macAddress)
.build();
}
public Builder toBuilder() {
return new AutoValue_NetworkSettings_Details.Builder(this);
}
public static Builder builder() {
return new AutoValue_NetworkSettings_Details.Builder();
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder endpoint(String value);
public abstract Builder gateway(String value);
public abstract Builder ipAddress(String value);
public abstract Builder ipPrefixLen(int value);
public abstract Builder ipv6Gateway(String value);
public abstract Builder globalIPv6Address(String value);
public abstract Builder globalIPv6PrefixLen(int value);
public abstract Builder macAddress(String value);
public abstract Details build();
}
}

View File

@ -131,7 +131,7 @@ public class ContainerToNodeMetadataTest {
.node(null)
.build();
ProviderMetadata providerMetadata = EasyMock.createMock(ProviderMetadata.class);
expect(providerMetadata.getEndpoint()).andReturn("http://127.0.0.1:4243");
expect(providerMetadata.getEndpoint()).andReturn("http://127.0.0.1:4243").atLeastOnce();
replay(providerMetadata);
GroupNamingConvention.Factory namingConvention = Guice.createInjector().getInstance(GroupNamingConvention.Factory.class);
@ -177,7 +177,7 @@ public class ContainerToNodeMetadataTest {
private Function<State, NodeMetadata.Status> toPortableStatus() {
StateToStatus function = EasyMock.createMock(StateToStatus.class);
expect(function.apply(anyObject(State.class))).andReturn(NodeMetadata.Status.RUNNING);
expect(function.apply(anyObject(State.class))).andReturn(NodeMetadata.Status.RUNNING).atLeastOnce();
replay(function);
return function;
}
@ -193,11 +193,58 @@ public class ContainerToNodeMetadataTest {
assertEquals(node.getGroup(), "hopeful_mclean");
assertEquals(node.getImageId(), "af0f59f1c19eef9471c3b8c8d587c39b8f130560b54f3766931b37d76d5de4b6");
assertEquals(node.getLoginPort(), 49199);
assertEquals(node.getPrivateAddresses().size(), 1);
assertEquals(node.getPublicAddresses().size(), 1);
assertEquals(node.getPrivateAddresses(), ImmutableSet.of("172.17.0.2"));
assertEquals(node.getPublicAddresses(), ImmutableSet.of("127.0.0.1"));
}
public void testVirtualMachineWithNetworksToNodeMetadata() {
// Example networks taken from container.json
Container containerWithNetwork = container.toBuilder()
.networkSettings(container.networkSettings().toBuilder()
.networks(ImmutableMap.<String, NetworkSettings.Details>builder()
.put("JCLOUDS_NETWORK", NetworkSettings.Details.builder()
.endpoint("1a10519f808faf1181cfdf3d1d6dd93e19ede2d1c8fed82562a4c17c297c4db3")
.gateway("172.19.0.1")
.ipAddress("172.19.0.2")
.ipPrefixLen(16)
.ipv6Gateway("")
.globalIPv6Address("")
.globalIPv6PrefixLen(0)
.macAddress("02:42:ac:13:00:02")
.build())
.put("bridge", NetworkSettings.Details.builder()
.endpoint("9e8dcc0c8288938a923018fee0728cee8e6de7c01a5150738ee6e51c1caf8cf6")
.gateway("172.17.0.1")
.ipAddress("172.17.0.2")
.ipPrefixLen(16)
.ipv6Gateway("")
.globalIPv6Address("")
.globalIPv6PrefixLen(0)
.macAddress("02:42:ac:11:00:02")
.build())
.build())
.build())
.build();
Container mockContainer = mockContainer(containerWithNetwork);
NodeMetadata node = function.apply(mockContainer);
verify(mockContainer);
assertEquals(node.getId(), "6d35806c1bd2b25cd92bba2d2c2c5169dc2156f53ab45c2b62d76e2d2fee14a9");
assertEquals(node.getGroup(), "hopeful_mclean");
assertEquals(node.getImageId(), "af0f59f1c19eef9471c3b8c8d587c39b8f130560b54f3766931b37d76d5de4b6");
assertEquals(node.getLoginPort(), 49199);
assertEquals(node.getPrivateAddresses(), ImmutableSet.of("172.17.0.2", "172.19.0.2"));
assertEquals(node.getPublicAddresses(), ImmutableSet.of("127.0.0.1"));
}
private Container mockContainer() {
return mockContainer(container);
}
private Container mockContainer(Container container) {
Container mockContainer = EasyMock.createMock(Container.class);
expect(mockContainer.id()).andReturn(container.id());

View File

@ -55,12 +55,11 @@ public class ContainerParseTest extends BaseDockerParseTest<Container> {
.config(Config.builder()
.hostname("6c9932f478bd")
.env(ImmutableList.of("PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"))
.image("57e570db16baba1e8c0d6f3c15868ddb400f64ff76ec948e65c3ca3f15fb3587")
.image("zettio/weave")
.domainname("")
.user("")
.cmd(ImmutableList.of("-name", "7a:63:a2:39:7b:0f"))
.entrypoint(ImmutableList.of("/home/weave/weaver", "-iface", "ethwe", "-wait", "5"))
.image("zettio/weave")
.workingDir("/home/weave")
.exposedPorts(ImmutableMap.of("6783/tcp", ImmutableMap.of(), "6783/udp", ImmutableMap.of()))
.build())