add docker NetworkAPI

- bump api version to 1.21
- use `alpine/3.2` image for liveTests
- use `kwart/alpine-ext:3.2-ssh` image as ssh-able image
- assert request bodies created correctly in NetworkApiMockTest
This commit is contained in:
Andrea Turli 2015-11-10 16:49:59 +01:00
parent 746038e8b2
commit 33522b8945
27 changed files with 1228 additions and 183 deletions

View File

@ -8,7 +8,7 @@ Please follow these steps to configure your workstation for jclouds-docker:
- install the latest Docker release (please visit https://docs.docker.com/installation/)
If you are using `boot2docker` then it can also manage certificates and help you setup `DOCKER_CERT_PATH` and `DOCKER_HOST` environment variables. (See `boot2docker shellinit`)
If you are using `docker-machine` then it can also manage certificates and help you setup `DOCKER_CERT_PATH` and `DOCKER_HOST` environment variables.
Assuming these environment variables are setup correctly there are no further setups steps are required.
@ -48,7 +48,7 @@ As jclouds docker support is quite new, issues may occasionally arise. Please fo
1. Remove all containers
$ docker rm `docker ps -a`
$ docker rm -f `docker ps -a`
2. remove all the images

View File

@ -34,7 +34,7 @@
<packaging>bundle</packaging>
<properties>
<test.docker.api-version>1.19</test.docker.api-version>
<test.docker.api-version>1.21</test.docker.api-version>
<test.docker.identity>${env.DOCKER_CERT_PATH}/cert.pem</test.docker.identity>
<test.docker.credential>${env.DOCKER_CERT_PATH}/key.pem</test.docker.credential>
<test.docker.cacert.path>${env.DOCKER_CERT_PATH}/ca.pem</test.docker.cacert.path>

View File

@ -16,13 +16,14 @@
*/
package org.jclouds.docker;
import java.io.Closeable;
import org.jclouds.docker.features.ContainerApi;
import org.jclouds.docker.features.ImageApi;
import org.jclouds.docker.features.MiscApi;
import org.jclouds.docker.features.NetworkApi;
import org.jclouds.rest.annotations.Delegate;
import java.io.Closeable;
public interface DockerApi extends Closeable {
@Delegate
@ -34,4 +35,7 @@ public interface DockerApi extends Closeable {
@Delegate
ImageApi getImageApi();
@Delegate
NetworkApi getNetworkApi();
}

View File

@ -16,9 +16,11 @@
*/
package org.jclouds.docker;
import com.google.auto.service.AutoService;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
import static org.jclouds.reflect.Reflection2.typeToken;
import java.net.URI;
import java.util.Properties;
import org.jclouds.Constants;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.compute.ComputeServiceContext;
@ -28,11 +30,9 @@ import org.jclouds.docker.config.DockerHttpApiModule;
import org.jclouds.docker.config.DockerParserModule;
import org.jclouds.rest.internal.BaseHttpApiMetadata;
import java.net.URI;
import java.util.Properties;
import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
import static org.jclouds.reflect.Reflection2.typeToken;
import com.google.auto.service.AutoService;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
@AutoService(ApiMetadata.class)
public class DockerApiMetadata extends BaseHttpApiMetadata<DockerApi> {
@ -70,7 +70,7 @@ public class DockerApiMetadata extends BaseHttpApiMetadata<DockerApi> {
.identityName("Path to certificate .pem file")
.credentialName("Path to key .pem file")
.documentation(URI.create("https://docs.docker.com/reference/api/docker_remote_api/"))
.version("1.16")
.version("1.21")
.defaultEndpoint("https://127.0.0.1:2376")
.defaultProperties(DockerApiMetadata.defaultProperties())
.view(typeToken(ComputeServiceContext.class))

View File

@ -18,7 +18,6 @@ package org.jclouds.docker.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.find;
import java.util.List;
import java.util.Map;
import java.util.Set;

View File

@ -0,0 +1,107 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.docker.domain;
import static org.jclouds.docker.internal.NullSafeCopies.copyOf;
import java.util.List;
import java.util.Map;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;
import com.google.auto.value.AutoValue;
@AutoValue
public abstract class Network {
@AutoValue
public abstract static class IPAM {
IPAM() {} // For AutoValue only!
@Nullable
public abstract String driver();
public abstract List<Config> config();
@SerializedNames({"Driver", "Config"})
public static IPAM create(String driver, List<Config> config) {
return new AutoValue_Network_IPAM(driver, copyOf(config));
}
@AutoValue
public abstract static class Config {
Config() {} // For AutoValue only!
public abstract String subnet();
@Nullable
public abstract String ipRange();
@Nullable
public abstract String gateway();
@SerializedNames({"Subnet", "IPRange", "Gateway"})
public static Config create(String subnet, String ipRange, String gateway) {
return new AutoValue_Network_IPAM_Config(subnet, ipRange, gateway);
}
}
}
@AutoValue
public abstract static class Details {
Details() {} // For AutoValue only!
public abstract String endpoint();
public abstract String macAddress();
public abstract String ipv4address();
public abstract String ipv6address();
@SerializedNames({ "EndpointID", "MacAddress", "IPv4Address", "IPv6Address" })
public static Details create(String endpoint, String macAddress, String ipv4address, String ipv6address) {
return new AutoValue_Network_Details(endpoint, macAddress, ipv4address, ipv6address);
}
}
@Nullable public abstract String name();
@Nullable public abstract String id();
@Nullable public abstract String scope();
@Nullable public abstract String driver();
@Nullable public abstract IPAM ipam();
public abstract Map<String, Details> containers();
public abstract Map<String, String> options();
Network() {}
@SerializedNames({ "Name", "Id", "Scope", "Driver", "IPAM", "Containers", "Options" })
public static Network create(String name, String id, String scope, String driver, IPAM ipam,
Map<String, Details> containers, Map<String, String> options) {
return new AutoValue_Network(name, id, scope, driver, ipam, copyOf(containers), copyOf(options));
}
}

View File

@ -18,7 +18,6 @@ package org.jclouds.docker.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.docker.internal.NullSafeCopies.copyOf;
import java.util.List;
import java.util.Map;
@ -27,28 +26,98 @@ import org.jclouds.json.SerializedNames;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@AutoValue
public abstract class NetworkSettings {
@AutoValue
public abstract static class Details {
Details() {} // For AutoValue only!
public abstract String endpoint();
public abstract String gateway();
public abstract String ipAddress();
public abstract int ipPrefixLen();
public abstract String ipv6Gateway();
public abstract String globalIPv6Address();
public abstract int globalIPv6PrefixLen();
public abstract String macAddress();
@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);
}
}
public abstract String bridge();
@Nullable public abstract String sandboxId();
public abstract boolean hairpinMode();
@Nullable public abstract String linkLocalIPv6Address();
public abstract int linkLocalIPv6PrefixLen();
@Nullable public abstract Map<String, List<Map<String, String>>> ports();
@Nullable public abstract String sandboxKey();
public abstract List<String> secondaryIPAddresses();
public abstract List<String> secondaryIPv6Addresses();
@Nullable public abstract String endpointId();
public abstract String gateway();
@Nullable public abstract String globalIPv6Address();
public abstract int globalIPv6PrefixLen();
public abstract String ipAddress();
public abstract int ipPrefixLen();
public abstract String gateway();
@Nullable public abstract String ipv6Gateway();
public abstract String bridge();
@Nullable public abstract String macAddress();
public abstract Map<String, Details> networks();
@Nullable public abstract String portMapping();
public abstract Map<String, List<Map<String, String>>> ports();
NetworkSettings() {
}
@SerializedNames({ "IPAddress", "IPPrefixLen", "Gateway", "Bridge", "PortMapping", "Ports" })
public static NetworkSettings create(String ipAddress, int ipPrefixLen, String gateway, String bridge,
String portMapping, Map<String, List<Map<String, String>>> ports) {
return new AutoValue_NetworkSettings(ipAddress, ipPrefixLen, gateway, bridge, portMapping, copyOf(ports));
@SerializedNames({ "Bridge", "SandboxID", "HairpinMode", "LinkLocalIPv6Address",
"LinkLocalIPv6PrefixLen", "Ports", "SandboxKey", "SecondaryIPAddresses",
"SecondaryIPv6Addresses", "EndpointID", "Gateway", "GlobalIPv6Address",
"GlobalIPv6PrefixLen", "IPAddress", "IPPrefixLen", "IPv6Gateway",
"MacAddress", "Networks", "PortMapping" })
public static NetworkSettings create(String bridge, String sandboxId, boolean hairpinMode, String linkLocalIPv6Address,
int linkLocalIPv6PrefixLen, Map<String, List<Map<String, String>>> ports, String sandboxKey, List<String> secondaryIPAddresses,
List<String> secondaryIPv6Addresses, String endpointId, String gateway, String globalIPv6Address,
int globalIPv6PrefixLen, String ipAddress, int ipPrefixLen, String ipv6Gateway,
String macAddress, Map<String, Details> networks, String portMapping) {
return new AutoValue_NetworkSettings(
bridge, sandboxId, hairpinMode, linkLocalIPv6Address,
linkLocalIPv6PrefixLen, ports, sandboxKey, copyOf(secondaryIPAddresses), copyOf(secondaryIPv6Addresses),
endpointId, gateway, globalIPv6Address, globalIPv6PrefixLen,
ipAddress, ipPrefixLen, ipv6Gateway,
macAddress, copyOf(networks), portMapping);
}
public static Builder builder() {
@ -67,6 +136,19 @@ public abstract class NetworkSettings {
private String bridge;
private String portMapping;
private Map<String, List<Map<String, String>>> ports = ImmutableMap.of();
private String sandboxId;
private boolean hairpinMode;
private String linkLocalIPv6Address;
private int linkLocalIPv6PrefixLen;
private String sandboxKey;
private List<String> secondaryIPAddresses = Lists.newArrayList();
private List<String> secondaryIPv6Addresses = Lists.newArrayList();
private String endpointId;
private String globalIPv6Address;
private int globalIPv6PrefixLen;
private String ipv6Gateway;
private String macAddress;
private Map<String, Details> networks = Maps.newHashMap();
public Builder ipAddress(String ipAddress) {
this.ipAddress = ipAddress;
@ -98,13 +180,84 @@ public abstract class NetworkSettings {
return this;
}
public Builder sandboxId(String sandboxId) {
this.sandboxId = sandboxId;
return this;
}
public Builder hairpinMode(boolean hairpinMode) {
this.hairpinMode = hairpinMode;
return this;
}
public Builder linkLocalIPv6Address(String linkLocalIPv6Address) {
this.linkLocalIPv6Address = linkLocalIPv6Address;
return this;
}
public Builder linkLocalIPv6PrefixLen(int linkLocalIPv6PrefixLen) {
this.linkLocalIPv6PrefixLen = linkLocalIPv6PrefixLen;
return this;
}
public Builder sandboxKey(String sandboxKey) {
this.sandboxKey = sandboxKey;
return this;
}
public Builder secondaryIPAddresses(List<String> secondaryIPAddresses) {
this.secondaryIPAddresses = secondaryIPAddresses;
return this;
}
public Builder secondaryIPv6Addresses(List<String> secondaryIPv6Addresses) {
this.secondaryIPv6Addresses = secondaryIPv6Addresses;
return this;
}
public Builder endpointId(String endpointId) {
this.endpointId = endpointId;
return this;
}
public Builder globalIPv6Address(String globalIPv6Address) {
this.globalIPv6Address = globalIPv6Address;
return this;
}
public Builder globalIPv6PrefixLen(int globalIPv6PrefixLen) {
this.globalIPv6PrefixLen = globalIPv6PrefixLen;
return this;
}
public Builder ipv6Gateway(String ipv6Gateway) {
this.ipv6Gateway = ipv6Gateway;
return this;
}
public Builder macAddress(String macAddress) {
this.macAddress = macAddress;
return this;
}
public Builder networks(Map<String, Details> networks) {
this.networks.putAll(networks);
return this;
}
public NetworkSettings build() {
return NetworkSettings.create(ipAddress, ipPrefixLen, gateway, bridge, portMapping, ports);
return NetworkSettings.create(bridge, sandboxId, hairpinMode, linkLocalIPv6Address, linkLocalIPv6PrefixLen, ports,
sandboxKey, secondaryIPAddresses, secondaryIPv6Addresses, endpointId, gateway,
globalIPv6Address, globalIPv6PrefixLen, ipAddress, ipPrefixLen, ipv6Gateway, macAddress, networks, portMapping);
}
public Builder fromNetworkSettings(NetworkSettings in) {
return this.ipAddress(in.ipAddress()).ipPrefixLen(in.ipPrefixLen()).gateway(in.gateway()).bridge(in.bridge())
.portMapping(in.portMapping()).ports(in.ports());
.portMapping(in.portMapping()).ports(in.ports()).sandboxId(in.sandboxId()).hairpinMode(in.hairpinMode()).linkLocalIPv6Address(in
.linkLocalIPv6Address()).linkLocalIPv6PrefixLen(in.linkLocalIPv6PrefixLen()).sandboxKey(in.sandboxKey()).secondaryIPAddresses(in
.secondaryIPAddresses()).secondaryIPv6Addresses(in.secondaryIPv6Addresses()).endpointId(in.endpointId()).globalIPv6Address(in
.globalIPv6Address()).globalIPv6PrefixLen(in.globalIPv6PrefixLen()).ipv6Gateway(in.ipv6Gateway()).macAddress(in.macAddress())
.networks(in.networks());
}
}

View File

@ -16,12 +16,15 @@
*/
package org.jclouds.docker.domain;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;
import com.google.auto.value.AutoValue;
@AutoValue
public abstract class State {
public abstract int pid();
public abstract boolean running();
@ -36,12 +39,20 @@ public abstract class State {
public abstract boolean restarting();
@Nullable public abstract String status();
@Nullable public abstract boolean oomKilled();
@Nullable public abstract boolean dead();
@Nullable public abstract String error();
State() {
}
@SerializedNames({ "Pid", "Running", "ExitCode", "StartedAt", "FinishedAt", "Paused", "Restarting" })
@SerializedNames({ "Pid", "Running", "ExitCode", "StartedAt", "FinishedAt", "Paused", "Restarting", "Status", "OOMKilled", "Dead", "Error" })
public static State create(int pid, boolean running, int exitCode, String startedAt, String finishedAt,
boolean paused, boolean restarting) {
return new AutoValue_State(pid, running, exitCode, startedAt, finishedAt, paused, restarting);
boolean paused, boolean restarting, String status, boolean oomKilled, boolean dead, String error) {
return new AutoValue_State(pid, running, exitCode, startedAt, finishedAt, paused, restarting, status, oomKilled, dead, error);
}
}

View File

@ -0,0 +1,100 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.docker.features;
import java.util.List;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.docker.domain.Network;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.binders.BindToJsonPayload;
@Consumes(MediaType.APPLICATION_JSON)
@Path("/v{jclouds.api-version}/networks")
public interface NetworkApi {
/**
* @return a set of networks
*/
@Named("networks:list")
@GET
@Fallback(EmptyListOnNotFoundOr404.class)
List<Network> listNetworks();
/**
* @param network the networks configuration (@see BindToJsonPayload)
* @return a new network
*/
@Named("network:create")
@POST
@Path("/create")
Network createNetwork(@BinderParam(BindToJsonPayload.class) Network network);
/**
* Return low-level information on the network id
* @param networkIdOrName The id or name of the network to get.
* @return The details of the network or <code>null</code> if the network with the given id doesn't exist.
*/
@Named("network:inspect")
@GET
@Path("/{idOrName}")
@Fallback(NullOnNotFoundOr404.class)
Network inspectNetwork(@PathParam("idOrName") String networkIdOrName);
/**
* @param networkIdOrName The id or name of the network to be removed.
*/
@Named("network:delete")
@DELETE
@Path("/{idOrName}")
void removeNetwork(@PathParam("idOrName") String networkIdOrName);
/**
* @param networkIdOrName The id or name of the network where the container will be attached.
*/
@Named("network:connectContainer")
@POST
@Path("/{idOrName}/connect")
@Payload("%7B\"Container\":\"{containerIdOrName}\"%7D")
@Headers(keys = "Content-Type", values = "application/json")
void connectContainerToNetwork(@PathParam("idOrName") String networkIdOrName, @PayloadParam("containerIdOrName") String containerIdOrName);
/**
* @param networkIdOrName The id or name of the network where the container was attached.
*/
@Named("network:disconnectContainer")
@POST
@Path("/{idOrName}/disconnect")
@Payload("%7B\"Container\":\"{containerIdOrName}\"%7D")
@Headers(keys = "Content-Type", values = "application/json")
void disconnectContainerFromNetwork(@PathParam("idOrName") String networkIdOrName, @PayloadParam("containerIdOrName") String containerIdOrName);
}

View File

@ -45,6 +45,11 @@ import com.google.inject.Module;
@Test(groups = "live")
public class BaseDockerApiLiveTest extends BaseApiLiveTest<DockerApi> {
protected static final String DEFAULT_IMAGE = "alpine";
protected static final String DEFAULT_TAG = "3.2";
protected static final String ALPINE_IMAGE_TAG = String.format("%s:%s", DEFAULT_IMAGE, DEFAULT_TAG);
public BaseDockerApiLiveTest() {
provider = "docker";
}

View File

@ -22,7 +22,6 @@ import static org.testng.Assert.assertNotNull;
import java.util.Properties;
import java.util.Random;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Template;
@ -48,13 +47,12 @@ import com.google.inject.Module;
@Test(groups = "live", singleThreaded = true, testName = "DockerComputeServiceAdapterLiveTest")
public class DockerComputeServiceAdapterLiveTest extends BaseDockerApiLiveTest {
private static final String SSHABLE_IMAGE = "tutum/ubuntu";
private static final String SSHABLE_IMAGE_TAG = "trusty";
private static final String SSHABLE_IMAGE = "kwart/alpine-ext";
private static final String SSHABLE_IMAGE_TAG = "3.2-ssh";
private Image defaultImage;
private DockerComputeServiceAdapter adapter;
private TemplateBuilder templateBuilder;
private ComputeService computeService;
private NodeAndInitialCredentials<Container> guest;
@BeforeClass
@ -75,7 +73,6 @@ public class DockerComputeServiceAdapterLiveTest extends BaseDockerApiLiveTest {
Injector injector = newBuilder().modules(modules).overrides(props).buildInjector();
adapter = injector.getInstance(DockerComputeServiceAdapter.class);
templateBuilder = injector.getInstance(TemplateBuilder.class);
computeService = injector.getInstance(ComputeService.class);
return injector.getInstance(DockerApi.class);
}

View File

@ -96,7 +96,11 @@ public class ContainerToNodeMetadataTest {
"2014-03-24T20:28:37.537659054Z", // startedAt
"0001-01-01T00:00:00Z", // finishedAt
false, // paused
false // restarting
false, // restarting
"running", // Status
false, // OOMKilled
false, // Dead
"" // Error
);
container = Container.builder()
.id("6d35806c1bd2b25cd92bba2d2c2c5169dc2156f53ab45c2b62d76e2d2fee14a9")

View File

@ -19,6 +19,9 @@ package org.jclouds.docker.config;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.util.List;
import java.util.Map;
import org.jclouds.docker.domain.Container;
import org.jclouds.docker.domain.NetworkSettings;
import org.jclouds.docker.domain.Port;
@ -53,8 +56,70 @@ public class DockerParserModuleTest {
}
public void networkSettings() {
String text = "{\"IPAddress\":\"XX.XX.206.98\",\"IPPrefixLen\":27,\"Gateway\":\"XX.XX.206.105\",\"Bridge\":\"public\",\"Ports\":{}}";
NetworkSettings settings = NetworkSettings.create("XX.XX.206.98", 27, "XX.XX.206.105", "public", null, null);
String text = "{" +
"\"Bridge\":\"\"," +
"\"SandboxID\":\"3ef128b055eb9ef62a6a2c281d97a2dfde5f47947d490f1dd2a81612611d961f\"," +
"\"HairpinMode\":false," +
"\"LinkLocalIPv6Address\":\"\"," +
"\"LinkLocalIPv6PrefixLen\":0," +
"\"Ports\":{}," +
"\"SandboxKey\":\"/var/run/docker/netns/3ef128b055eb\"," +
"\"SecondaryIPAddresses\":[]," +
"\"SecondaryIPv6Addresses\":[]," +
"\"EndpointID\":\"9e8dcc0c8288938a923018fee0728cee8e6de7c01a5150738ee6e51c1caf8cf6\"," +
"\"Gateway\":\"172.17.0.1\"," +
"\"GlobalIPv6Address\":\"\"," +
"\"GlobalIPv6PrefixLen\":0," +
"\"IPAddress\":\"172.17.0.2\"," +
"\"IPPrefixLen\":16," +
"\"IPv6Gateway\":\"\"," +
"\"MacAddress\":\"02:42:ac:11:00:02\"," +
"\"Networks\":{" +
"\"bridge\":{" +
"\"EndpointID\":\"9e8dcc0c8288938a923018fee0728cee8e6de7c01a5150738ee6e51c1caf8cf6\"," +
"\"Gateway\":\"172.17.0.1\"," +
"\"IPAddress\":\"172.17.0.2\"," +
"\"IPPrefixLen\":16," +
"\"IPv6Gateway\":\"\"," +
"\"GlobalIPv6Address\":\"\"," +
"\"GlobalIPv6PrefixLen\":0," +
"\"MacAddress\":\"02:42:ac:11:00:02\"" +
"}" +
"}" +
"}";
NetworkSettings settings = NetworkSettings.create(
"", // Bridge
"3ef128b055eb9ef62a6a2c281d97a2dfde5f47947d490f1dd2a81612611d961f", // SandboxID
false, // HairpinMode
"", // LinkLocalIPv6Address
0, // LinkLocalIPv6PrefixLen
ImmutableMap.<String, List<Map<String, String>>> of(), // Ports
"/var/run/docker/netns/3ef128b055eb", // SandboxKey
null, // SecondaryIPAddresses
null, // SecondaryIPv6Addresses
"9e8dcc0c8288938a923018fee0728cee8e6de7c01a5150738ee6e51c1caf8cf6", // EndpointID
"172.17.0.1", // Gateway
"", // GlobalIPv6Address
0, // GlobalIPv6PrefixLen
"172.17.0.2", // IPAddress
16, // IPPrefixLen
"", // IPv6Gateway
"02:42:ac:11:00:02", // MacAddress
ImmutableMap.of(
"bridge", NetworkSettings.Details.create(
"9e8dcc0c8288938a923018fee0728cee8e6de7c01a5150738ee6e51c1caf8cf6", // EndpointID
"172.17.0.1", // Gateway
"172.17.0.2", // IPAddress
16, // IPPrefixLen
"", // IPv6Gateway
"", // GlobalIPv6Address
0, // GlobalIPv6PrefixLen
"02:42:ac:11:00:02" // MacAddress
)
),
null // PortMapping
);
assertEquals(json.fromJson(text, NetworkSettings.class), settings);
assertEquals(json.toJson(settings), text);
}

View File

@ -47,17 +47,16 @@ import com.google.common.collect.ImmutableList;
public class ContainerApiLiveTest extends BaseDockerApiLiveTest {
private Container container = null;
protected static final String BUSYBOX_IMAGE_TAG = "busybox:ubuntu-12.04";
protected Image image = null;
@BeforeClass
protected void init() {
if (api.getImageApi().inspectImage(BUSYBOX_IMAGE_TAG) == null) {
CreateImageOptions options = CreateImageOptions.Builder.fromImage(BUSYBOX_IMAGE_TAG);
if (api.getImageApi().inspectImage(ALPINE_IMAGE_TAG) == null) {
CreateImageOptions options = CreateImageOptions.Builder.fromImage(ALPINE_IMAGE_TAG);
InputStream createImageStream = api.getImageApi().createImage(options);
consumeStream(createImageStream);
}
image = api.getImageApi().inspectImage(BUSYBOX_IMAGE_TAG);
image = api.getImageApi().inspectImage(ALPINE_IMAGE_TAG);
assertNotNull(image);
}
@ -69,7 +68,7 @@ public class ContainerApiLiveTest extends BaseDockerApiLiveTest {
}
}
if (image != null) {
api.getImageApi().deleteImage(BUSYBOX_IMAGE_TAG);
api.getImageApi().deleteImage(ALPINE_IMAGE_TAG);
}
}

View File

@ -78,7 +78,7 @@ public class ContainerApiMockTest extends BaseDockerMockTest {
public void testGetContainer() throws Exception {
MockWebServer server = mockWebServer(new MockResponse().setBody(payloadFromResource("/container.json")));
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString(), new DockerParserModule()).getContainerApi();
String containerId = "b03d4cd15b76f8876110615cdeed15eadf77c9beb408d62f1687dcc69192cd6d";
String containerId = "e475abdf3e139a5e1e158b38b6cb290a1bec856d39d5a951f015dfb8fcba7331";
try {
assertEquals(api.inspectContainer(containerId), new ContainerParseTest().expected());
assertSent(server, "GET", "/containers/" + containerId + "/json");

View File

@ -35,9 +35,6 @@ import com.google.common.collect.Iterables;
@Test(groups = "live", testName = "ImageApiLiveTest", singleThreaded = true)
public class ImageApiLiveTest extends BaseDockerApiLiveTest {
private static final String DEFAULT_IMAGE = "busybox";
private static final String DEFAULT_TAG = "ubuntu-14.04";
private Image image;
@Test

View File

@ -51,8 +51,6 @@ import com.google.common.collect.Iterables;
@Test(groups = "live", testName = "MiscApiLiveTest", singleThreaded = true)
public class MiscApiLiveTest extends BaseDockerApiLiveTest {
protected static final String BUSYBOX_IMAGE_TAG = "busybox:ubuntu-12.04";
private static String imageId;
private Container container = null;
@ -61,12 +59,12 @@ public class MiscApiLiveTest extends BaseDockerApiLiveTest {
@BeforeClass
protected void init() {
if (api.getImageApi().inspectImage(BUSYBOX_IMAGE_TAG) == null) {
CreateImageOptions options = CreateImageOptions.Builder.fromImage(BUSYBOX_IMAGE_TAG);
if (api.getImageApi().inspectImage(ALPINE_IMAGE_TAG) == null) {
CreateImageOptions options = CreateImageOptions.Builder.fromImage(ALPINE_IMAGE_TAG);
InputStream createImageStream = api.getImageApi().createImage(options);
consumeStream(createImageStream);
}
image = api.getImageApi().inspectImage(BUSYBOX_IMAGE_TAG);
image = api.getImageApi().inspectImage(ALPINE_IMAGE_TAG);
assertNotNull(image);
Config containerConfig = Config.builder().image(image.id())
.cmd(ImmutableList.of("/bin/sh", "-c", "touch hello; while true; do echo hello world; sleep 1; done"))
@ -85,7 +83,7 @@ public class MiscApiLiveTest extends BaseDockerApiLiveTest {
}
}
if (image != null) {
api.getImageApi().deleteImage(BUSYBOX_IMAGE_TAG);
api.getImageApi().deleteImage(ALPINE_IMAGE_TAG);
}
}
@ -107,7 +105,7 @@ public class MiscApiLiveTest extends BaseDockerApiLiveTest {
@Test
public void testBuildImageFromDockerfile() throws IOException, InterruptedException, URISyntaxException {
BuildOptions options = BuildOptions.Builder.tag("testBuildImage").verbose(false).nocache(false);
BuildOptions options = BuildOptions.Builder.tag("jclouds-test-test-build-image").verbose(false).nocache(false);
InputStream buildImageStream = api().build(tarredDockerfile(), options);
String buildStream = consumeStream(buildImageStream);
Iterable<String> splitted = Splitter.on("\n").split(buildStream.replace("\r", "").trim());

View File

@ -0,0 +1,125 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.docker.features;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.jclouds.docker.compute.BaseDockerApiLiveTest;
import org.jclouds.docker.domain.Config;
import org.jclouds.docker.domain.Container;
import org.jclouds.docker.domain.Image;
import org.jclouds.docker.domain.Network;
import org.jclouds.docker.options.CreateImageOptions;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@Test(groups = "live", testName = "NetworkApiLiveTest", singleThreaded = true)
public class NetworkApiLiveTest extends BaseDockerApiLiveTest {
private static final String NETWORK_NAME = "JCLOUDS_NETWORK";
private Network network = null;
protected Image image = null;
private Container container;
@BeforeClass
protected void init() {
if (api.getImageApi().inspectImage(ALPINE_IMAGE_TAG) == null) {
CreateImageOptions options = CreateImageOptions.Builder.fromImage(ALPINE_IMAGE_TAG);
InputStream createImageStream = api.getImageApi().createImage(options);
consumeStream(createImageStream);
}
image = api.getImageApi().inspectImage(ALPINE_IMAGE_TAG);
assertNotNull(image);
Config containerConfig = Config.builder().image(image.id())
.cmd(ImmutableList.of("sh", "-c", "touch hello; while true; do echo hello world; sleep 1; done"))
.build();
container = api.getContainerApi().createContainer("jclouds-test-network", containerConfig);
api.getContainerApi().startContainer(container.id());
container = api.getContainerApi().inspectContainer(container.id());
}
@AfterClass(alwaysRun = true)
protected void tearDown() {
if (container != null) {
api.getContainerApi().stopContainer(container.id());
api.getContainerApi().removeContainer(container.id());
}
if (network != null) {
api().removeNetwork(network.id());
}
}
public void testCreateNetwork() throws IOException, InterruptedException {
network = api().createNetwork(Network.create(NETWORK_NAME, null, null, null, null, ImmutableMap.<String, Network.Details> of(), ImmutableMap.<String, String> of()));
assertNotNull(network);
assertNotNull(network.id());
}
@Test(dependsOnMethods = "testCreateNetwork")
public void testGetNetwork() {
network = api().inspectNetwork(network.id());
assertNotNull(network);
}
@Test(dependsOnMethods = "testGetNetwork")
public void testAttachContainerToNetwork() {
api().connectContainerToNetwork(network.id(), container.id());
container = api.getContainerApi().inspectContainer(container.id());
assertTrue(Iterables.any(container.networkSettings().networks().keySet(), Predicates.equalTo(network.name())));
}
@Test(dependsOnMethods = "testAttachContainerToNetwork")
public void testDisconnectContainerFromNetwork() {
api().disconnectContainerFromNetwork(network.id(), container.id());
container = api.getContainerApi().inspectContainer(container.id());
assertFalse(Iterables.any(container.networkSettings().networks().keySet(), Predicates.equalTo(network.name())));
}
@Test(dependsOnMethods = "testCreateNetwork")
public void testListNetworks() {
List<Network> networks = api().listNetworks();
for (Network network : networks) {
assertNotNull(network.id());
}
}
@Test(dependsOnMethods = "testDisconnectContainerFromNetwork")
public void testRemoveNetwork() {
api().removeNetwork(network.id());
assertNull(api().inspectNetwork(network.id()));
network = null;
}
private NetworkApi api() {
return api.getNetworkApi();
}
}

View File

@ -0,0 +1,153 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.docker.features;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.util.Map;
import org.jclouds.docker.DockerApi;
import org.jclouds.docker.config.DockerParserModule;
import org.jclouds.docker.domain.Network;
import org.jclouds.docker.internal.BaseDockerMockTest;
import org.jclouds.docker.parse.NetworkParseTest;
import org.jclouds.docker.parse.NetworksParseTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
/**
* Mock tests for the {@link NetworkApi} class.
*/
@Test(groups = "unit", testName = "NetworkApiMockTest")
public class NetworkApiMockTest extends BaseDockerMockTest {
public void testListNetworks() throws Exception {
MockWebServer server = mockWebServer(new MockResponse().setBody(payloadFromResource("/networks.json")));
NetworkApi api = api(DockerApi.class, server.getUrl("/").toString()).getNetworkApi();
try {
assertEquals(api.listNetworks(), new NetworksParseTest().expected());
assertSent(server, "GET", "/networks");
} finally {
server.shutdown();
}
}
public void testListNonexistentNetworks() throws Exception {
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(404));
NetworkApi api = api(DockerApi.class, server.getUrl("/").toString()).getNetworkApi();
try {
assertEquals(api.listNetworks(), ImmutableList.of());
assertSent(server, "GET", "/networks");
} finally {
server.shutdown();
}
}
public void testGetNetwork() throws Exception {
MockWebServer server = mockWebServer(new MockResponse().setBody(payloadFromResource("/network.json")));
NetworkApi api = api(DockerApi.class, server.getUrl("/").toString(), new DockerParserModule()).getNetworkApi();
String networkId = "b03d4cd15b76f8876110615cdeed15eadf77c9beb408d62f1687dcc69192cd6d";
try {
assertEquals(api.inspectNetwork(networkId), new NetworkParseTest().expected());
assertSent(server, "GET", "/networks/" + networkId);
} finally {
server.shutdown();
}
}
public void testCreateNetwork() throws Exception {
MockWebServer server = mockWebServer(new MockResponse().setBody(payloadFromResource("/network-creation.json")));
NetworkApi api = api(DockerApi.class, server.getUrl("/").toString()).getNetworkApi();
Map<String, String> options = ImmutableMap.<String, String> builder()
.put("com.docker.network.bridge.default_bridge", "true")
.put("com.docker.network.bridge.enable_icc", "true")
.put("com.docker.network.bridge.enable_ip_masquerade", "true")
.put("com.docker.network.bridge.host_binding_ipv4", "0.0.0.0")
.put("com.docker.network.bridge.name", "docker0")
.put("com.docker.network.driver.mtu", "1500")
.build();
Network network = Network.create(
"isolated_nw", // Name
null, // Id
"bridge", // Driver
null, // Scope
Network.IPAM.create(
"default", // driver
ImmutableList.of(Network.IPAM.Config.create("172.17.0.0/16", null, null)) // config
),
ImmutableMap.of("39b69226f9d79f5634485fb236a23b2fe4e96a0a94128390a7fbbcc167065867",
Network.Details.create(
"ed2419a97c1d9954d05b46e462e7002ea552f216e9b136b80a7db8d98b442eda", //endpointId
"02:42:ac:11:00:02", // MAC
"172.17.0.2/16", // ipv4address
"" // ipv6address
)
),
options);
try {
Network created = api.createNetwork(network);
assertNotNull(created);
assertThat(created.id()).isEqualTo("22be93d5babb089c5aab8dbc369042fad48ff791584ca2da2100db837a1c7c30");
assertSent(server, "POST", "/networks/create", "{\"Name\":\"isolated_nw\",\"Scope\":\"bridge\",\"IPAM\":{\"Driver\":\"default\",\"Config\":[{\"Subnet\":\"172.17.0.0/16\"}]},\"Containers\":{\"39b69226f9d79f5634485fb236a23b2fe4e96a0a94128390a7fbbcc167065867\":{\"EndpointID\":\"ed2419a97c1d9954d05b46e462e7002ea552f216e9b136b80a7db8d98b442eda\",\"MacAddress\":\"02:42:ac:11:00:02\",\"IPv4Address\":\"172.17.0.2/16\",\"IPv6Address\":\"\"}},\"Options\":{\"com.docker.network.bridge.default_bridge\":\"true\",\"com.docker.network.bridge.enable_icc\":\"true\",\"com.docker.network.bridge.enable_ip_masquerade\":\"true\",\"com.docker.network.bridge.host_binding_ipv4\":\"0.0.0.0\",\"com.docker.network.bridge.name\":\"docker0\",\"com.docker.network.driver.mtu\":\"1500\"}}");
} finally {
server.shutdown();
}
}
public void testRemoveNetwork() throws Exception {
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(204));
NetworkApi api = api(DockerApi.class, server.getUrl("/").toString()).getNetworkApi();
String networkId = "6d35806c1bd2b25cd92bba2d2c2c5169dc2156f53ab45c2b62d76e2d2fee14a9";
try {
api.removeNetwork(networkId);
assertSent(server, "DELETE", "/networks/" + networkId);
} finally {
server.shutdown();
}
}
public void testConnectContainerToNetwork() throws Exception {
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(200));
NetworkApi api = api(DockerApi.class, server.getUrl("/").toString()).getNetworkApi();
try {
api.connectContainerToNetwork("123456789", "containerName");
assertSent(server, "POST", "/networks/123456789/connect", "{ \"Container\": \"containerName\" }");
} finally {
server.shutdown();
}
}
public void testDisconnectContainerFromNetwork() throws Exception {
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(200));
NetworkApi api = api(DockerApi.class, server.getUrl("/").toString()).getNetworkApi();
try {
api.disconnectContainerFromNetwork("123456789", "containerName");
assertSent(server, "POST", "/networks/123456789/disconnect", "{ \"Container\": \"containerName\" }");
} finally {
server.shutdown();
}
}
}

View File

@ -16,8 +16,11 @@
*/
package org.jclouds.docker.internal;
import static com.google.common.base.Charsets.UTF_8;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.assertj.core.api.Assertions.assertThat;
import static org.jclouds.util.Strings2.toStringAndClose;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
@ -29,6 +32,7 @@ import org.jclouds.http.okhttp.config.OkHttpCommandExecutorServiceModule;
import com.google.common.base.Charsets;
import com.google.common.base.Throwables;
import com.google.gson.JsonParser;
import com.google.inject.Module;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
@ -66,4 +70,15 @@ public class BaseDockerMockTest extends BaseMockWebServerTest {
return request;
}
protected RecordedRequest assertSent(MockWebServer server, String method, String path, String json)
throws InterruptedException {
RecordedRequest request = assertSent(server, method, path);
assertEquals(request.getHeader("Content-Type"), APPLICATION_JSON);
assertEquals(parser.parse(new String(request.getBody(), UTF_8)), parser.parse(json));
return request;
}
/** So that we can ignore formatting. */
private final JsonParser parser = new JsonParser();
}

View File

@ -63,17 +63,46 @@ public class ContainerParseTest extends BaseDockerParseTest<Container> {
.workingDir("/home/weave")
.exposedPorts(ImmutableMap.of("6783/tcp", ImmutableMap.of(), "6783/udp", ImmutableMap.of()))
.build())
.state(State.create(3939, true, 0, "2014-10-31T17:00:21.802008706Z", "0001-01-01T00:00:00Z", false, false))
.state(State.create(10357, true, 0, "2015-11-10T09:33:21.68146124Z", "0001-01-01T00:00:00Z", false, false, "running", false, false, ""))
.image("57e570db16baba1e8c0d6f3c15868ddb400f64ff76ec948e65c3ca3f15fb3587")
.networkSettings(NetworkSettings.builder()
.ipAddress("172.17.0.7")
.sandboxId("3ef128b055eb9ef62a6a2c281d97a2dfde5f47947d490f1dd2a81612611d961f")
.hairpinMode(false)
.linkLocalIPv6Address("")
.linkLocalIPv6PrefixLen(0)
.globalIPv6Address("")
.globalIPv6PrefixLen(0)
.ipv6Gateway("")
.sandboxKey("/var/run/docker/netns/3ef128b055eb")
.endpointId("9e8dcc0c8288938a923018fee0728cee8e6de7c01a5150738ee6e51c1caf8cf6")
.ipAddress("172.17.0.2")
.ipPrefixLen(16)
.gateway("172.17.42.1")
.bridge("docker0")
.ports(ImmutableMap.<String, List<Map<String, String>>>of(
"6783/tcp", ImmutableList.<Map<String, String>>of(ImmutableMap.of("HostIp", "0.0.0.0", "HostPort", "6783")),
"6783/udp", ImmutableList.<Map<String, String>>of(ImmutableMap.of("HostIp", "0.0.0.0", "HostPort", "6783")))
)
.gateway("172.17.0.1")
.bridge("")
.ports(ImmutableMap.<String, List<Map<String, String>>>of())
.macAddress("02:42:ac:11:00:02")
.networks(ImmutableMap.of(
"JCLOUDS_NETWORK", NetworkSettings.Details.create(
"04268fbb4dc368b5a53bb1c3f89294a4f0c72095deb944db3c4efc6d6a439304",
"172.19.0.1",
"172.19.0.2",
16,
"",
"",
0,
"02:42:ac:13:00:02"
),
"bridge", NetworkSettings.Details.create(
"9e8dcc0c8288938a923018fee0728cee8e6de7c01a5150738ee6e51c1caf8cf6",
"172.17.0.1",
"172.17.0.2",
16,
"",
"",
0,
"02:42:ac:11:00:02"
)
))
.build())
.resolvConfPath("/var/lib/docker/containers/6c9932f478bd761f32ddb54ed28ab42ab6fac6f2a279f561ea31503ee9d39524/resolv.conf")
.hostConfig(HostConfig.builder()

View File

@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.docker.parse;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import org.jclouds.docker.domain.Network;
import org.jclouds.docker.internal.BaseDockerParseTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@Test(groups = "unit")
public class NetworkParseTest extends BaseDockerParseTest<Network> {
@Override
public String resource() {
return "/network.json";
}
@Override
@Consumes(MediaType.APPLICATION_JSON)
public Network expected() {
Map<String, String> options = ImmutableMap.<String, String> builder()
.put("com.docker.network.bridge.default_bridge", "true")
.put("com.docker.network.bridge.enable_icc", "true")
.put("com.docker.network.bridge.enable_ip_masquerade", "true")
.put("com.docker.network.bridge.host_binding_ipv4", "0.0.0.0")
.put("com.docker.network.bridge.name", "docker0")
.put("com.docker.network.driver.mtu", "1500")
.build();
return Network.create(
"bridge", // Name
"f2de39df4171b0dc801e8002d1d999b77256983dfc63041c0f34030aa3977566", // Id
"local", // Scope
"bridge", // Driver
Network.IPAM.create(
"default", // driver
ImmutableList.of(Network.IPAM.Config.create("172.17.0.0/16", null, null)) // config
),
ImmutableMap.of("39b69226f9d79f5634485fb236a23b2fe4e96a0a94128390a7fbbcc167065867",
Network.Details.create(
"ed2419a97c1d9954d05b46e462e7002ea552f216e9b136b80a7db8d98b442eda", //endpointId
"02:42:ac:11:00:02", // MAC
"172.17.0.2/16", // ipv4address
"" // ipv6address
)
),
options);
}
}

View File

@ -0,0 +1,97 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.docker.parse;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import org.jclouds.docker.domain.Network;
import org.jclouds.docker.internal.BaseDockerParseTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@Test(groups = "unit")
public class NetworksParseTest extends BaseDockerParseTest<List<Network>> {
@Override
public String resource() {
return "/networks.json";
}
@Override
@Consumes(MediaType.APPLICATION_JSON)
public List<Network> expected() {
return ImmutableList.of(
Network.create(
"bridge", // Name
"f2de39df4171b0dc801e8002d1d999b77256983dfc63041c0f34030aa3977566", // Id
"local", // Scope
"bridge", // Driver
Network.IPAM.create(
"default", // driver
ImmutableList.of(Network.IPAM.Config.create("172.17.0.0/16", null, null)) // config
),
ImmutableMap.of("39b69226f9d79f5634485fb236a23b2fe4e96a0a94128390a7fbbcc167065867",
Network.Details.create(
"ed2419a97c1d9954d05b46e462e7002ea552f216e9b136b80a7db8d98b442eda", //endpointId
"02:42:ac:11:00:02", // MAC
"172.17.0.2/16", // ipv4address
"" // ipv6address
)
),
ImmutableMap.<String, String> builder()
.put("com.docker.network.bridge.default_bridge", "true")
.put("com.docker.network.bridge.enable_icc", "true")
.put("com.docker.network.bridge.enable_ip_masquerade", "true")
.put("com.docker.network.bridge.host_binding_ipv4", "0.0.0.0")
.put("com.docker.network.bridge.name", "docker0")
.put("com.docker.network.driver.mtu", "1500")
.build()
),
Network.create(
"none", // Name
"e086a3893b05ab69242d3c44e49483a3bbbd3a26b46baa8f61ab797c1088d794", // Id
"local", // Scope
"null", // Driver
Network.IPAM.create(
"default", // driver
ImmutableList.<Network.IPAM.Config>of() // config
),
ImmutableMap.<String, Network.Details> of(),
ImmutableMap.<String, String> of()
),
Network.create(
"host", // Name
"13e871235c677f196c4e1ecebb9dc733b9b2d2ab589e30c539efeda84a24215e", // Id
"local", // Scope
"host", // Driver
Network.IPAM.create(
"default", // driver
ImmutableList.<Network.IPAM.Config>of() // config
),
ImmutableMap.<String, Network.Details> of(),
ImmutableMap.<String, String> of()
)
);
}
}

View File

@ -1,129 +1,155 @@
{
"Args": [
"-iface",
"ethwe",
"-wait",
"5",
"-name",
"7a:63:a2:39:7b:0f"
"Args": [
"-iface",
"ethwe",
"-wait",
"5",
"-name",
"7a:63:a2:39:7b:0f"
],
"Config": {
"AttachStderr": false,
"AttachStdin": false,
"AttachStdout": false,
"Cmd": [
"-name",
"7a:63:a2:39:7b:0f"
],
"Config": {
"AttachStderr": false,
"AttachStdin": false,
"AttachStdout": false,
"Cmd": [
"-name",
"7a:63:a2:39:7b:0f"
],
"CpuShares": 0,
"Cpuset": "",
"Domainname": "",
"Entrypoint": [
"/home/weave/weaver",
"-iface",
"ethwe",
"-wait",
"5"
],
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"ExposedPorts": {
"6783/tcp": {},
"6783/udp": {}
},
"Hostname": "6c9932f478bd",
"Image": "zettio/weave",
"Memory": 0,
"MemorySwap": 0,
"NetworkDisabled": false,
"OnBuild": null,
"OpenStdin": false,
"PortSpecs": null,
"SecurityOpt": null,
"StdinOnce": false,
"Tty": false,
"User": "",
"Volumes": null,
"WorkingDir": "/home/weave"
"CpuShares": 0,
"Cpuset": "",
"Domainname": "",
"Entrypoint": [
"/home/weave/weaver",
"-iface",
"ethwe",
"-wait",
"5"
],
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"ExposedPorts": {
"6783/tcp": {},
"6783/udp": {}
},
"Created": "2014-10-31T17:00:21.544197943Z",
"Driver": "aufs",
"ExecDriver": "native-0.2",
"HostConfig": {
"Binds": null,
"CapAdd": null,
"CapDrop": null,
"ContainerIDFile": "",
"Devices": [],
"Dns": [ "8.8.8.8", "8.8.4.4" ],
"DnsSearch": null,
"ExtraHosts": [ "extra:169.254.0.1" ],
"Links": null,
"LxcConf": [],
"NetworkMode": "bridge",
"PortBindings": {
"6783/tcp": [
{
"HostIp": "",
"HostPort": "6783"
}
],
"6783/udp": [
{
"HostIp": "",
"HostPort": "6783"
}
]
},
"Privileged": true,
"PublishAllPorts": false,
"RestartPolicy": {
"MaximumRetryCount": 0,
"Name": ""
},
"VolumesFrom": null
},
"HostnamePath": "/var/lib/docker/containers/6c9932f478bd761f32ddb54ed28ab42ab6fac6f2a279f561ea31503ee9d39524/hostname",
"HostsPath": "/var/lib/docker/containers/6c9932f478bd761f32ddb54ed28ab42ab6fac6f2a279f561ea31503ee9d39524/hosts",
"Id": "6c9932f478bd761f32ddb54ed28ab42ab6fac6f2a279f561ea31503ee9d39524",
"Image": "57e570db16baba1e8c0d6f3c15868ddb400f64ff76ec948e65c3ca3f15fb3587",
"MountLabel": "",
"Name": "/weave",
"NetworkSettings": {
"Bridge": "docker0",
"Gateway": "172.17.42.1",
"IPAddress": "172.17.0.7",
"IPPrefixLen": 16,
"MacAddress": "02:42:ac:11:00:07",
"PortMapping": null,
"Ports": {
"6783/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "6783"
}
],
"6783/udp": [
{
"HostIp": "0.0.0.0",
"HostPort": "6783"
}
]
"Hostname": "6c9932f478bd",
"Image": "zettio/weave",
"Memory": 0,
"MemorySwap": 0,
"NetworkDisabled": false,
"OnBuild": null,
"OpenStdin": false,
"PortSpecs": null,
"SecurityOpt": null,
"StdinOnce": false,
"Tty": false,
"User": "",
"Volumes": null,
"WorkingDir": "/home/weave"
},
"Created": "2014-10-31T17:00:21.544197943Z",
"Driver": "aufs",
"ExecDriver": "native-0.2",
"HostConfig": {
"Binds": null,
"CapAdd": null,
"CapDrop": null,
"ContainerIDFile": "",
"Devices": [],
"Dns": [
"8.8.8.8",
"8.8.4.4"
],
"DnsSearch": null,
"ExtraHosts": ["extra:169.254.0.1"],
"Links": null,
"LxcConf": [],
"NetworkMode": "bridge",
"PortBindings": {
"6783/tcp": [
{
"HostIp": "",
"HostPort": "6783"
}
],
"6783/udp": [
{
"HostIp": "",
"HostPort": "6783"
}
]
},
"Path": "/home/weave/weaver",
"ProcessLabel": "",
"ResolvConfPath": "/var/lib/docker/containers/6c9932f478bd761f32ddb54ed28ab42ab6fac6f2a279f561ea31503ee9d39524/resolv.conf",
"State": {
"ExitCode": 0,
"FinishedAt": "0001-01-01T00:00:00Z",
"Paused": false,
"Pid": 3939,
"Restarting": false,
"Running": true,
"StartedAt": "2014-10-31T17:00:21.802008706Z"
"Privileged": true,
"PublishAllPorts": false,
"RestartPolicy": {
"MaximumRetryCount": 0,
"Name": ""
},
"Volumes": {},
"VolumesRW": {}
"VolumesFrom": null
},
"HostnamePath": "/var/lib/docker/containers/6c9932f478bd761f32ddb54ed28ab42ab6fac6f2a279f561ea31503ee9d39524/hostname",
"HostsPath": "/var/lib/docker/containers/6c9932f478bd761f32ddb54ed28ab42ab6fac6f2a279f561ea31503ee9d39524/hosts",
"Id": "6c9932f478bd761f32ddb54ed28ab42ab6fac6f2a279f561ea31503ee9d39524",
"Image": "57e570db16baba1e8c0d6f3c15868ddb400f64ff76ec948e65c3ca3f15fb3587",
"MountLabel": "",
"Name": "/weave",
"NetworkSettings": {
"Bridge": "",
"SandboxID": "3ef128b055eb9ef62a6a2c281d97a2dfde5f47947d490f1dd2a81612611d961f",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/3ef128b055eb",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "9e8dcc0c8288938a923018fee0728cee8e6de7c01a5150738ee6e51c1caf8cf6",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"JCLOUDS_NETWORK": {
"EndpointID": "04268fbb4dc368b5a53bb1c3f89294a4f0c72095deb944db3c4efc6d6a439304",
"Gateway": "172.19.0.1",
"IPAddress": "172.19.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:13:00:02"
},
"bridge": {
"EndpointID": "9e8dcc0c8288938a923018fee0728cee8e6de7c01a5150738ee6e51c1caf8cf6",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02"
}
}
},
"Path": "/home/weave/weaver",
"ProcessLabel": "",
"ResolvConfPath": "/var/lib/docker/containers/6c9932f478bd761f32ddb54ed28ab42ab6fac6f2a279f561ea31503ee9d39524/resolv.conf",
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 10357,
"ExitCode": 0,
"Error": "",
"StartedAt": "2015-11-10T09:33:21.68146124Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Volumes": {},
"VolumesRW": {}
}

View File

@ -0,0 +1,4 @@
{
"Id": "22be93d5babb089c5aab8dbc369042fad48ff791584ca2da2100db837a1c7c30",
"Warning": ""
}

View File

@ -0,0 +1,30 @@
{
"Name": "bridge",
"Id": "f2de39df4171b0dc801e8002d1d999b77256983dfc63041c0f34030aa3977566",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Config": [
{
"Subnet": "172.17.0.0/16"
}
]
},
"Containers": {
"39b69226f9d79f5634485fb236a23b2fe4e96a0a94128390a7fbbcc167065867": {
"EndpointID": "ed2419a97c1d9954d05b46e462e7002ea552f216e9b136b80a7db8d98b442eda",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
}
}

View File

@ -0,0 +1,56 @@
[
{
"Name": "bridge",
"Id": "f2de39df4171b0dc801e8002d1d999b77256983dfc63041c0f34030aa3977566",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Config": [
{
"Subnet": "172.17.0.0/16"
}
]
},
"Containers": {
"39b69226f9d79f5634485fb236a23b2fe4e96a0a94128390a7fbbcc167065867": {
"EndpointID": "ed2419a97c1d9954d05b46e462e7002ea552f216e9b136b80a7db8d98b442eda",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
}
},
{
"Name": "none",
"Id": "e086a3893b05ab69242d3c44e49483a3bbbd3a26b46baa8f61ab797c1088d794",
"Scope": "local",
"Driver": "null",
"IPAM": {
"Driver": "default",
"Config": []
},
"Containers": {},
"Options": {}
},
{
"Name": "host",
"Id": "13e871235c677f196c4e1ecebb9dc733b9b2d2ab589e30c539efeda84a24215e",
"Scope": "local",
"Driver": "host",
"IPAM": {
"Driver": "default",
"Config": []
},
"Containers": {},
"Options": {}
}
]