From 866b9835a674d1552f035849a0871d6198872934 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Fri, 8 Apr 2016 14:20:54 +0200 Subject: [PATCH] Migrate traefik to engine-api The docker provider now uses docker/engine-api and vdemeester/docker-events instead of fsouza-dockerclient. Signed-off-by: Vincent Demeester --- glide.lock | 37 ++-- glide.yaml | 5 +- provider/docker.go | 161 ++++++++++------ provider/docker_test.go | 416 +++++++++++++++++++++++++--------------- 4 files changed, 387 insertions(+), 232 deletions(-) diff --git a/glide.lock b/glide.lock index 5837a7e7a..61c0c7726 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 2e15595ec349ec462fa2b0a52e26e3f3dcbd17fed66dad9a1e1c2e2c0385fe49 -updated: 2016-04-02T15:25:37.354420171+02:00 +hash: 79b6eb2a613b5e2ce5c57150eec41ac04def3f232a3613fd8b5a88b5e1041b38 +updated: 2016-04-02T15:42:37.505896092+02:00 imports: - name: github.com/alecthomas/template version: b867cc6ab45cece8143cfcc6fc9c77cf3f2c23c0 @@ -89,10 +89,18 @@ imports: - types/container - types/filters - types/strslice + - client/transport + - client/transport/cancellable + - types/network + - types/registry + - types/time + - types/blkiodev - name: github.com/docker/go-connections version: f549a9393d05688dff0992ef3efd8bbe6c628aeb subpackages: - nat + - sockets + - tlsconfig - name: github.com/docker/go-units version: 5d2041e26a699eaca682e2ea41c8f891e1060444 - name: github.com/docker/libcompose @@ -113,26 +121,6 @@ imports: version: d5cac425555ca5cf00694df246e04f05e6a55150 - name: github.com/flynn/go-shlex version: 3f9db97f856818214da2e1057f8ad84803971cff -- name: github.com/fsouza/go-dockerclient - version: a49c8269a6899cae30da1f8a4b82e0ce945f9967 - subpackages: - - external/github.com/docker/docker/opts - - external/github.com/docker/docker/pkg/archive - - external/github.com/docker/docker/pkg/fileutils - - external/github.com/docker/docker/pkg/homedir - - external/github.com/docker/docker/pkg/stdcopy - - external/github.com/hashicorp/go-cleanhttp - - external/github.com/Sirupsen/logrus - - external/github.com/docker/docker/pkg/idtools - - external/github.com/docker/docker/pkg/ioutils - - external/github.com/docker/docker/pkg/longpath - - external/github.com/docker/docker/pkg/pools - - external/github.com/docker/docker/pkg/promise - - external/github.com/docker/docker/pkg/system - - external/github.com/opencontainers/runc/libcontainer/user - - external/golang.org/x/sys/unix - - external/golang.org/x/net/context - - external/github.com/docker/go-units - name: github.com/gambol99/go-marathon version: ade11d1dc2884ee1f387078fc28509559b6235d1 - name: github.com/go-check/check @@ -182,6 +170,8 @@ imports: version: 565402cd71fbd9c12aa7e295324ea357e970a61e - name: github.com/mailgun/timetools version: fd192d755b00c968d312d23f521eb0cdc6f66bd0 +- name: github.com/Microsoft/go-winio + version: 9e2895e5f6c3f16473b91d37fae6e89990a4520c - name: github.com/miekg/dns version: 7e024ce8ce18b21b475ac6baf8fa3c42536bf2fa - name: github.com/mitchellh/mapstructure @@ -223,6 +213,8 @@ imports: version: 54ed61c2b47e263ae2f01b86837b0c4bd1da28e8 - name: github.com/unrolled/render version: 26b4e3aac686940fe29521545afad9966ddfc80c +- name: github.com/vdemeester/docker-events + version: bd72e1848b08db4b5ed1a2e9277621b9f5e5d1f3 - name: github.com/vdemeester/libkermit version: 7e4e689a6fa9281e0fb9b7b9c297e22d5342a5ec - name: github.com/vdemeester/shakers @@ -257,6 +249,7 @@ imports: subpackages: - context - publicsuffix + - proxy - name: golang.org/x/sys version: eb2c74142fd19a79b3f237334c7384d5167b1b46 subpackages: diff --git a/glide.yaml b/glide.yaml index 7cd60afb4..8fb072c59 100644 --- a/glide.yaml +++ b/glide.yaml @@ -52,8 +52,6 @@ import: ref: 26b4e3aac686940fe29521545afad9966ddfc80c - package: github.com/flynn/go-shlex ref: 3f9db97f856818214da2e1057f8ad84803971cff - - package: github.com/fsouza/go-dockerclient - ref: a49c8269a6899cae30da1f8a4b82e0ce945f9967 - package: github.com/boltdb/bolt ref: 51f99c862475898df9773747d3accd05a7ca33c1 - package: gopkg.in/mgo.v2 @@ -168,8 +166,11 @@ import: - types/container - types/filters - types/strslice + - package: github.com/vdemeester/docker-events - package: github.com/docker/go-connections subpackages: - nat + - sockets + - tlsconfig - package: github.com/docker/go-units - package: github.com/mailgun/multibuf diff --git a/provider/docker.go b/provider/docker.go index 2ad18ee4c..f18cb80d7 100644 --- a/provider/docker.go +++ b/provider/docker.go @@ -2,19 +2,31 @@ package provider import ( "errors" + "net/http" "strconv" "strings" "text/template" "time" + "golang.org/x/net/context" + "github.com/BurntSushi/ty/fun" log "github.com/Sirupsen/logrus" "github.com/cenkalti/backoff" "github.com/containous/traefik/safe" "github.com/containous/traefik/types" - "github.com/fsouza/go-dockerclient" + "github.com/docker/engine-api/client" + dockertypes "github.com/docker/engine-api/types" + eventtypes "github.com/docker/engine-api/types/events" + "github.com/docker/engine-api/types/filters" + "github.com/docker/go-connections/sockets" + "github.com/docker/go-connections/tlsconfig" + "github.com/vdemeester/docker-events" ) +// DockerAPIVersion is a constant holding the version of the Docker API traefik will use +const DockerAPIVersion string = "1.21" + // Docker holds configurations of the Docker provider. type Docker struct { BaseProvider `mapstructure:",squash"` @@ -31,59 +43,94 @@ type DockerTLS struct { InsecureSkipVerify bool } +func (provider *Docker) createClient() (client.APIClient, error) { + var httpClient *http.Client + httpHeaders := map[string]string{ + // FIXME(vdemeester) use version here O:) + "User-Agent": "Traefik", + } + if provider.TLS != nil { + tlsOptions := tlsconfig.Options{ + CAFile: provider.TLS.CA, + CertFile: provider.TLS.Cert, + KeyFile: provider.TLS.Key, + InsecureSkipVerify: provider.TLS.InsecureSkipVerify, + } + config, err := tlsconfig.Client(tlsOptions) + if err != nil { + return nil, err + } + tr := &http.Transport{ + TLSClientConfig: config, + } + proto, addr, _, err := client.ParseHost(provider.Endpoint) + if err != nil { + return nil, err + } + + sockets.ConfigureTransport(tr, proto, addr) + + httpClient = &http.Client{ + Transport: tr, + } + } + return client.NewClient(provider.Endpoint, DockerAPIVersion, httpClient, httpHeaders) +} + // Provide allows the provider to provide configurations to traefik // using the given configuration channel. func (provider *Docker) Provide(configurationChan chan<- types.ConfigMessage) error { safe.Go(func() { operation := func() error { - var dockerClient *docker.Client var err error - if provider.TLS != nil { - dockerClient, err = docker.NewTLSClient(provider.Endpoint, - provider.TLS.Cert, provider.TLS.Key, provider.TLS.CA) - if err == nil { - dockerClient.TLSConfig.InsecureSkipVerify = provider.TLS.InsecureSkipVerify - } - } else { - dockerClient, err = docker.NewClient(provider.Endpoint) - } + dockerClient, err := provider.createClient() if err != nil { log.Errorf("Failed to create a client for docker, error: %s", err) return err } - err = dockerClient.Ping() + version, err := dockerClient.ServerVersion(context.Background()) + log.Debugf("Docker connection established with docker %s (API %s)", version.Version, version.APIVersion) + containers, err := listContainers(dockerClient) if err != nil { - log.Errorf("Docker connection error %+v", err) + log.Errorf("Failed to list containers for docker, error %s", err) return err } - log.Debug("Docker connection established") - configuration := provider.loadDockerConfig(listContainers(dockerClient)) + configuration := provider.loadDockerConfig(containers) configurationChan <- types.ConfigMessage{ ProviderName: "docker", Configuration: configuration, } if provider.Watch { - dockerEvents := make(chan *docker.APIEvents) - dockerClient.AddEventListener(dockerEvents) - log.Debug("Docker listening") - for { - event := <-dockerEvents - if event == nil { - return errors.New("Docker event nil") - // log.Fatalf("Docker connection error") + ctx, cancel := context.WithCancel(context.Background()) + f := filters.NewArgs() + f.Add("type", "container") + options := dockertypes.EventsOptions{ + Filters: f, + } + eventHandler := events.NewHandler(events.ByAction) + startStopHandle := func(m eventtypes.Message) { + log.Debugf("Docker event received %+v", m) + containers, err := listContainers(dockerClient) + if err != nil { + log.Errorf("Failed to list containers for docker, error %s", err) + // Call cancel to get out of the monitor + cancel() } - if event.Status == "start" || event.Status == "die" { - log.Debugf("Docker event receveived %+v", event) - configuration := provider.loadDockerConfig(listContainers(dockerClient)) - if configuration != nil { - configurationChan <- types.ConfigMessage{ - ProviderName: "docker", - Configuration: configuration, - } + configuration := provider.loadDockerConfig(containers) + if configuration != nil { + configurationChan <- types.ConfigMessage{ + ProviderName: "docker", + Configuration: configuration, } } } + eventHandler.Handle("start", startStopHandle) + eventHandler.Handle("die", startStopHandle) + errChan := events.MonitorWithHandler(ctx, dockerClient, options, eventHandler) + if err := <-errChan; err != nil { + return err + } } return nil } @@ -99,7 +146,7 @@ func (provider *Docker) Provide(configurationChan chan<- types.ConfigMessage) er return nil } -func (provider *Docker) loadDockerConfig(containersInspected []docker.Container) *types.Configuration { +func (provider *Docker) loadDockerConfig(containersInspected []dockertypes.ContainerJSON) *types.Configuration { var DockerFuncMap = template.FuncMap{ "getBackend": provider.getBackend, "getPort": provider.getPort, @@ -113,16 +160,16 @@ func (provider *Docker) loadDockerConfig(containersInspected []docker.Container) } // filter containers - filteredContainers := fun.Filter(containerFilter, containersInspected).([]docker.Container) + filteredContainers := fun.Filter(containerFilter, containersInspected).([]dockertypes.ContainerJSON) - frontends := map[string][]docker.Container{} + frontends := map[string][]dockertypes.ContainerJSON{} for _, container := range filteredContainers { frontends[provider.getFrontendName(container)] = append(frontends[provider.getFrontendName(container)], container) } templateObjects := struct { - Containers []docker.Container - Frontends map[string][]docker.Container + Containers []dockertypes.ContainerJSON + Frontends map[string][]dockertypes.ContainerJSON Domain string }{ filteredContainers, @@ -137,7 +184,7 @@ func (provider *Docker) loadDockerConfig(containersInspected []docker.Container) return configuration } -func containerFilter(container docker.Container) bool { +func containerFilter(container dockertypes.ContainerJSON) bool { if len(container.NetworkSettings.Ports) == 0 { log.Debugf("Filtering container without port %s", container.Name) return false @@ -156,14 +203,14 @@ func containerFilter(container docker.Container) bool { return true } -func (provider *Docker) getFrontendName(container docker.Container) string { +func (provider *Docker) getFrontendName(container dockertypes.ContainerJSON) string { // Replace '.' with '-' in quoted keys because of this issue https://github.com/BurntSushi/toml/issues/78 return normalize(provider.getFrontendRule(container)) } // GetFrontendRule returns the frontend rule for the specified container, using // it's label. It returns a default one (Host) if the label is not present. -func (provider *Docker) getFrontendRule(container docker.Container) string { +func (provider *Docker) getFrontendRule(container dockertypes.ContainerJSON) string { // ⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠ // TODO: backwards compatibility with DEPRECATED rule.Value if value, ok := container.Config.Labels["traefik.frontend.value"]; ok { @@ -179,14 +226,14 @@ func (provider *Docker) getFrontendRule(container docker.Container) string { return "Host:" + getEscapedName(container.Name) + "." + provider.Domain } -func (provider *Docker) getBackend(container docker.Container) string { +func (provider *Docker) getBackend(container dockertypes.ContainerJSON) string { if label, err := getLabel(container, "traefik.backend"); err == nil { return label } return normalize(container.Name) } -func (provider *Docker) getPort(container docker.Container) string { +func (provider *Docker) getPort(container dockertypes.ContainerJSON) string { if label, err := getLabel(container, "traefik.port"); err == nil { return label } @@ -196,42 +243,42 @@ func (provider *Docker) getPort(container docker.Container) string { return "" } -func (provider *Docker) getWeight(container docker.Container) string { +func (provider *Docker) getWeight(container dockertypes.ContainerJSON) string { if label, err := getLabel(container, "traefik.weight"); err == nil { return label } return "1" } -func (provider *Docker) getDomain(container docker.Container) string { +func (provider *Docker) getDomain(container dockertypes.ContainerJSON) string { if label, err := getLabel(container, "traefik.domain"); err == nil { return label } return provider.Domain } -func (provider *Docker) getProtocol(container docker.Container) string { +func (provider *Docker) getProtocol(container dockertypes.ContainerJSON) string { if label, err := getLabel(container, "traefik.protocol"); err == nil { return label } return "http" } -func (provider *Docker) getPassHostHeader(container docker.Container) string { +func (provider *Docker) getPassHostHeader(container dockertypes.ContainerJSON) string { if passHostHeader, err := getLabel(container, "traefik.frontend.passHostHeader"); err == nil { return passHostHeader } return "false" } -func (provider *Docker) getEntryPoints(container docker.Container) []string { +func (provider *Docker) getEntryPoints(container dockertypes.ContainerJSON) []string { if entryPoints, err := getLabel(container, "traefik.frontend.entryPoints"); err == nil { return strings.Split(entryPoints, ",") } return []string{} } -func getLabel(container docker.Container, label string) (string, error) { +func getLabel(container dockertypes.ContainerJSON, label string) (string, error) { for key, value := range container.Config.Labels { if key == label { return value, nil @@ -240,7 +287,7 @@ func getLabel(container docker.Container, label string) (string, error) { return "", errors.New("Label not found:" + label) } -func getLabels(container docker.Container, labels []string) (map[string]string, error) { +func getLabels(container dockertypes.ContainerJSON, labels []string) (map[string]string, error) { var globalErr error foundLabels := map[string]string{} for _, label := range labels { @@ -256,14 +303,20 @@ func getLabels(container docker.Container, labels []string) (map[string]string, return foundLabels, globalErr } -func listContainers(dockerClient *docker.Client) []docker.Container { - containerList, _ := dockerClient.ListContainers(docker.ListContainersOptions{}) - containersInspected := []docker.Container{} +func listContainers(dockerClient client.APIClient) ([]dockertypes.ContainerJSON, error) { + containerList, err := dockerClient.ContainerList(context.Background(), dockertypes.ContainerListOptions{}) + if err != nil { + return []dockertypes.ContainerJSON{}, err + } + containersInspected := []dockertypes.ContainerJSON{} // get inspect containers for _, container := range containerList { - containerInspected, _ := dockerClient.InspectContainer(container.ID) - containersInspected = append(containersInspected, *containerInspected) + containerInspected, err := dockerClient.ContainerInspect(context.Background(), container.ID) + if err != nil { + log.Warnf("Failed to inpsect container %s, error: %s", container.ID, err) + } + containersInspected = append(containersInspected, containerInspected) } - return containersInspected + return containersInspected, nil } diff --git a/provider/docker_test.go b/provider/docker_test.go index 0dfb585f3..175b83d0a 100644 --- a/provider/docker_test.go +++ b/provider/docker_test.go @@ -6,7 +6,10 @@ import ( "testing" "github.com/containous/traefik/types" - "github.com/fsouza/go-dockerclient" + docker "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/container" + "github.com/docker/engine-api/types/network" + "github.com/docker/go-connections/nat" ) func TestDockerGetFrontendName(t *testing.T) { @@ -15,20 +18,24 @@ func TestDockerGetFrontendName(t *testing.T) { } containers := []struct { - container docker.Container + container docker.ContainerJSON expected string }{ { - container: docker.Container{ - Name: "foo", - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "foo", + }, + Config: &container.Config{}, }, expected: "Host-foo-docker-localhost", }, { - container: docker.Container{ - Name: "bar", - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "bar", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.frontend.rule": "Headers:User-Agent,bat/0.1.0", }, @@ -37,9 +44,11 @@ func TestDockerGetFrontendName(t *testing.T) { expected: "Headers-User-Agent-bat-0-1-0", }, { - container: docker.Container{ - Name: "test", - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.frontend.rule": "Host:foo.bar", }, @@ -48,9 +57,11 @@ func TestDockerGetFrontendName(t *testing.T) { expected: "Host-foo-bar", }, { - container: docker.Container{ - Name: "test", - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.frontend.rule": "Path:/test", }, @@ -59,9 +70,11 @@ func TestDockerGetFrontendName(t *testing.T) { expected: "Path-test", }, { - container: docker.Container{ - Name: "test", - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.frontend.rule": "PathPrefix:/test2", }, @@ -85,27 +98,33 @@ func TestDockerGetFrontendRule(t *testing.T) { } containers := []struct { - container docker.Container + container docker.ContainerJSON expected string }{ { - container: docker.Container{ - Name: "foo", - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "foo", + }, + Config: &container.Config{}, }, expected: "Host:foo.docker.localhost", }, { - container: docker.Container{ - Name: "bar", - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "bar", + }, + Config: &container.Config{}, }, expected: "Host:bar.docker.localhost", }, { - container: docker.Container{ - Name: "test", - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.frontend.rule": "Host:foo.bar", }, @@ -114,9 +133,11 @@ func TestDockerGetFrontendRule(t *testing.T) { expected: "Host:foo.bar", }, { - container: docker.Container{ - Name: "test", - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.frontend.rule": "Path:/test", }, @@ -138,27 +159,33 @@ func TestDockerGetBackend(t *testing.T) { provider := &Docker{} containers := []struct { - container docker.Container + container docker.ContainerJSON expected string }{ { - container: docker.Container{ - Name: "foo", - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "foo", + }, + Config: &container.Config{}, }, expected: "foo", }, { - container: docker.Container{ - Name: "bar", - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "bar", + }, + Config: &container.Config{}, }, expected: "bar", }, { - container: docker.Container{ - Name: "test", - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.backend": "foobar", }, @@ -180,24 +207,30 @@ func TestDockerGetPort(t *testing.T) { provider := &Docker{} containers := []struct { - container docker.Container + container docker.ContainerJSON expected string }{ { - container: docker.Container{ - Name: "foo", - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "foo", + }, + Config: &container.Config{}, NetworkSettings: &docker.NetworkSettings{}, }, expected: "", }, { - container: docker.Container{ - Name: "bar", - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "bar", + }, + Config: &container.Config{}, NetworkSettings: &docker.NetworkSettings{ - Ports: map[docker.Port][]docker.PortBinding{ - "80/tcp": {}, + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + }, }, }, }, @@ -205,9 +238,9 @@ func TestDockerGetPort(t *testing.T) { }, // FIXME handle this better.. // { - // container: docker.Container{ + // container: docker.ContainerJSON{ // Name: "bar", - // Config: &docker.Config{}, + // Config: &container.Config{}, // NetworkSettings: &docker.NetworkSettings{ // Ports: map[docker.Port][]docker.PortBinding{ // "80/tcp": []docker.PortBinding{}, @@ -218,16 +251,20 @@ func TestDockerGetPort(t *testing.T) { // expected: "80", // }, { - container: docker.Container{ - Name: "test", - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.port": "8080", }, }, NetworkSettings: &docker.NetworkSettings{ - Ports: map[docker.Port][]docker.PortBinding{ - "80/tcp": {}, + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + }, }, }, }, @@ -247,20 +284,24 @@ func TestDockerGetWeight(t *testing.T) { provider := &Docker{} containers := []struct { - container docker.Container + container docker.ContainerJSON expected string }{ { - container: docker.Container{ - Name: "foo", - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "foo", + }, + Config: &container.Config{}, }, expected: "1", }, { - container: docker.Container{ - Name: "test", - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.weight": "10", }, @@ -284,20 +325,24 @@ func TestDockerGetDomain(t *testing.T) { } containers := []struct { - container docker.Container + container docker.ContainerJSON expected string }{ { - container: docker.Container{ - Name: "foo", - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "foo", + }, + Config: &container.Config{}, }, expected: "docker.localhost", }, { - container: docker.Container{ - Name: "test", - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.domain": "foo.bar", }, @@ -319,20 +364,24 @@ func TestDockerGetProtocol(t *testing.T) { provider := &Docker{} containers := []struct { - container docker.Container + container docker.ContainerJSON expected string }{ { - container: docker.Container{ - Name: "foo", - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "foo", + }, + Config: &container.Config{}, }, expected: "http", }, { - container: docker.Container{ - Name: "test", - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.protocol": "https", }, @@ -354,20 +403,24 @@ func TestDockerGetPassHostHeader(t *testing.T) { provider := &Docker{} containers := []struct { - container docker.Container + container docker.ContainerJSON expected string }{ { - container: docker.Container{ - Name: "foo", - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "foo", + }, + Config: &container.Config{}, }, expected: "false", }, { - container: docker.Container{ - Name: "test", - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.frontend.passHostHeader": "true", }, @@ -387,18 +440,18 @@ func TestDockerGetPassHostHeader(t *testing.T) { func TestDockerGetLabel(t *testing.T) { containers := []struct { - container docker.Container + container docker.ContainerJSON expected string }{ { - container: docker.Container{ - Config: &docker.Config{}, + container: docker.ContainerJSON{ + Config: &container.Config{}, }, expected: "Label not found:", }, { - container: docker.Container{ - Config: &docker.Config{ + container: docker.ContainerJSON{ + Config: &container.Config{ Labels: map[string]string{ "foo": "bar", }, @@ -424,20 +477,20 @@ func TestDockerGetLabel(t *testing.T) { func TestDockerGetLabels(t *testing.T) { containers := []struct { - container docker.Container + container docker.ContainerJSON expectedLabels map[string]string expectedError string }{ { - container: docker.Container{ - Config: &docker.Config{}, + container: docker.ContainerJSON{ + Config: &container.Config{}, }, expectedLabels: map[string]string{}, expectedError: "Label not found:", }, { - container: docker.Container{ - Config: &docker.Config{ + container: docker.ContainerJSON{ + Config: &container.Config{ Labels: map[string]string{ "foo": "fooz", }, @@ -449,8 +502,8 @@ func TestDockerGetLabels(t *testing.T) { expectedError: "Label not found: bar", }, { - container: docker.Container{ - Config: &docker.Config{ + container: docker.ContainerJSON{ + Config: &container.Config{ Labels: map[string]string{ "foo": "fooz", "bar": "barz", @@ -480,125 +533,168 @@ func TestDockerGetLabels(t *testing.T) { func TestDockerTraefikFilter(t *testing.T) { containers := []struct { - container docker.Container + container docker.ContainerJSON expected bool }{ { - container: docker.Container{ - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "container", + }, + Config: &container.Config{}, NetworkSettings: &docker.NetworkSettings{}, }, expected: false, }, { - container: docker.Container{ - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "container", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.enable": "false", }, }, NetworkSettings: &docker.NetworkSettings{ - Ports: map[docker.Port][]docker.PortBinding{ - "80/tcp": {}, + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + }, }, }, }, expected: false, }, { - container: docker.Container{ - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "container", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.frontend.rule": "Host:foo.bar", }, }, NetworkSettings: &docker.NetworkSettings{ - Ports: map[docker.Port][]docker.PortBinding{ - "80/tcp": {}, + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + }, }, }, }, expected: true, }, { - container: docker.Container{ - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "container", + }, + Config: &container.Config{}, NetworkSettings: &docker.NetworkSettings{ - Ports: map[docker.Port][]docker.PortBinding{ - "80/tcp": {}, - "443/tcp": {}, + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + "443/tcp": {}, + }, }, }, }, expected: false, }, { - container: docker.Container{ - Config: &docker.Config{}, + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "container", + }, + Config: &container.Config{}, NetworkSettings: &docker.NetworkSettings{ - Ports: map[docker.Port][]docker.PortBinding{ - "80/tcp": {}, + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + }, }, }, }, expected: true, }, { - container: docker.Container{ - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "container", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.port": "80", }, }, NetworkSettings: &docker.NetworkSettings{ - Ports: map[docker.Port][]docker.PortBinding{ - "80/tcp": {}, - "443/tcp": {}, + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + "443/tcp": {}, + }, }, }, }, expected: true, }, { - container: docker.Container{ - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "container", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.enable": "true", }, }, NetworkSettings: &docker.NetworkSettings{ - Ports: map[docker.Port][]docker.PortBinding{ - "80/tcp": {}, + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + }, }, }, }, expected: true, }, { - container: docker.Container{ - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "container", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.enable": "anything", }, }, NetworkSettings: &docker.NetworkSettings{ - Ports: map[docker.Port][]docker.PortBinding{ - "80/tcp": {}, + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + }, }, }, }, expected: true, }, { - container: docker.Container{ - Config: &docker.Config{ + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "container", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.frontend.rule": "Host:foo.bar", }, }, NetworkSettings: &docker.NetworkSettings{ - Ports: map[docker.Port][]docker.PortBinding{ - "80/tcp": {}, + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + }, }, }, }, @@ -616,26 +712,30 @@ func TestDockerTraefikFilter(t *testing.T) { func TestDockerLoadDockerConfig(t *testing.T) { cases := []struct { - containers []docker.Container + containers []docker.ContainerJSON expectedFrontends map[string]*types.Frontend expectedBackends map[string]*types.Backend }{ { - containers: []docker.Container{}, + containers: []docker.ContainerJSON{}, expectedFrontends: map[string]*types.Frontend{}, expectedBackends: map[string]*types.Backend{}, }, { - containers: []docker.Container{ + containers: []docker.ContainerJSON{ { - Name: "test", - Config: &docker.Config{}, + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test", + }, + Config: &container.Config{}, NetworkSettings: &docker.NetworkSettings{ - Ports: map[docker.Port][]docker.PortBinding{ - "80/tcp": {}, + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + }, }, - Networks: map[string]docker.ContainerNetwork{ - "bridgde": { + Networks: map[string]*network.EndpointSettings{ + "bridge": { IPAddress: "127.0.0.1", }, }, @@ -667,38 +767,46 @@ func TestDockerLoadDockerConfig(t *testing.T) { }, }, { - containers: []docker.Container{ + containers: []docker.ContainerJSON{ { - Name: "test1", - Config: &docker.Config{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test1", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.backend": "foobar", "traefik.frontend.entryPoints": "http,https", }, }, NetworkSettings: &docker.NetworkSettings{ - Ports: map[docker.Port][]docker.PortBinding{ - "80/tcp": {}, + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + }, }, - Networks: map[string]docker.ContainerNetwork{ - "bridgde": { + Networks: map[string]*network.EndpointSettings{ + "bridge": { IPAddress: "127.0.0.1", }, }, }, }, { - Name: "test2", - Config: &docker.Config{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "test2", + }, + Config: &container.Config{ Labels: map[string]string{ "traefik.backend": "foobar", }, }, NetworkSettings: &docker.NetworkSettings{ - Ports: map[docker.Port][]docker.PortBinding{ - "80/tcp": {}, + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + }, }, - Networks: map[string]docker.ContainerNetwork{ + Networks: map[string]*network.EndpointSettings{ "bridge": { IPAddress: "127.0.0.1", },