1
0
Fork 0

Merge branch v2.11 into v3.5

This commit is contained in:
romain 2025-08-26 17:35:37 +02:00
commit c2db9db1aa
30 changed files with 356 additions and 307 deletions

View file

@ -357,6 +357,25 @@ func (c *Configuration) SetEffectiveConfiguration() {
}
}
for _, resolver := range c.CertificatesResolvers {
if resolver.ACME == nil {
continue
}
if resolver.ACME.DNSChallenge == nil {
continue
}
switch resolver.ACME.DNSChallenge.Provider {
case "googledomains", "cloudxns", "brandit":
log.Warn().Msgf("%s DNS provider is deprecated.", resolver.ACME.DNSChallenge.Provider)
case "dnspod":
log.Warn().Msgf("%s provider is deprecated, please use 'tencentcloud' provider instead.", resolver.ACME.DNSChallenge.Provider)
case "azure":
log.Warn().Msgf("%s provider is deprecated, please use 'azuredns' provider instead.", resolver.ACME.DNSChallenge.Provider)
}
}
c.initACMEProvider()
}

View file

@ -1,22 +1,21 @@
package docker
import (
dockertypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/swarm"
containertypes "github.com/docker/docker/api/types/container"
networktypes "github.com/docker/docker/api/types/network"
swarmtypes "github.com/docker/docker/api/types/swarm"
"github.com/docker/go-connections/nat"
)
func containerJSON(ops ...func(*dockertypes.ContainerJSON)) dockertypes.ContainerJSON {
c := &dockertypes.ContainerJSON{
ContainerJSONBase: &dockertypes.ContainerJSONBase{
func containerJSON(ops ...func(*containertypes.InspectResponse)) containertypes.InspectResponse {
c := &containertypes.InspectResponse{
ContainerJSONBase: &containertypes.ContainerJSONBase{
Name: "fake",
HostConfig: &container.HostConfig{},
HostConfig: &containertypes.HostConfig{},
},
Config: &container.Config{},
NetworkSettings: &dockertypes.NetworkSettings{
NetworkSettingsBase: dockertypes.NetworkSettingsBase{},
Config: &containertypes.Config{},
NetworkSettings: &containertypes.NetworkSettings{
NetworkSettingsBase: containertypes.NetworkSettingsBase{},
},
}
@ -27,58 +26,50 @@ func containerJSON(ops ...func(*dockertypes.ContainerJSON)) dockertypes.Containe
return *c
}
func name(name string) func(*dockertypes.ContainerJSON) {
return func(c *dockertypes.ContainerJSON) {
func name(name string) func(*containertypes.InspectResponse) {
return func(c *containertypes.InspectResponse) {
c.ContainerJSONBase.Name = name
}
}
func networkMode(mode string) func(*dockertypes.ContainerJSON) {
return func(c *dockertypes.ContainerJSON) {
c.ContainerJSONBase.HostConfig.NetworkMode = container.NetworkMode(mode)
func networkMode(mode string) func(*containertypes.InspectResponse) {
return func(c *containertypes.InspectResponse) {
c.ContainerJSONBase.HostConfig.NetworkMode = containertypes.NetworkMode(mode)
}
}
func nodeIP(ip string) func(*dockertypes.ContainerJSON) {
return func(c *dockertypes.ContainerJSON) {
c.ContainerJSONBase.Node = &dockertypes.ContainerNode{
IPAddress: ip,
}
}
}
func ports(portMap nat.PortMap) func(*dockertypes.ContainerJSON) {
return func(c *dockertypes.ContainerJSON) {
func ports(portMap nat.PortMap) func(*containertypes.InspectResponse) {
return func(c *containertypes.InspectResponse) {
c.NetworkSettings.NetworkSettingsBase.Ports = portMap
}
}
func withNetwork(name string, ops ...func(*network.EndpointSettings)) func(*dockertypes.ContainerJSON) {
return func(c *dockertypes.ContainerJSON) {
func withNetwork(name string, ops ...func(*networktypes.EndpointSettings)) func(*containertypes.InspectResponse) {
return func(c *containertypes.InspectResponse) {
if c.NetworkSettings.Networks == nil {
c.NetworkSettings.Networks = map[string]*network.EndpointSettings{}
c.NetworkSettings.Networks = map[string]*networktypes.EndpointSettings{}
}
c.NetworkSettings.Networks[name] = &network.EndpointSettings{}
c.NetworkSettings.Networks[name] = &networktypes.EndpointSettings{}
for _, op := range ops {
op(c.NetworkSettings.Networks[name])
}
}
}
func ipv4(ip string) func(*network.EndpointSettings) {
return func(s *network.EndpointSettings) {
func ipv4(ip string) func(*networktypes.EndpointSettings) {
return func(s *networktypes.EndpointSettings) {
s.IPAddress = ip
}
}
func ipv6(ip string) func(*network.EndpointSettings) {
return func(s *network.EndpointSettings) {
func ipv6(ip string) func(*networktypes.EndpointSettings) {
return func(s *networktypes.EndpointSettings) {
s.GlobalIPv6Address = ip
}
}
func swarmTask(id string, ops ...func(*swarm.Task)) swarm.Task {
task := &swarm.Task{
func swarmTask(id string, ops ...func(*swarmtypes.Task)) swarmtypes.Task {
task := &swarmtypes.Task{
ID: id,
}
@ -89,22 +80,28 @@ func swarmTask(id string, ops ...func(*swarm.Task)) swarm.Task {
return *task
}
func taskSlot(slot int) func(*swarm.Task) {
return func(task *swarm.Task) {
func taskSlot(slot int) func(*swarmtypes.Task) {
return func(task *swarmtypes.Task) {
task.Slot = slot
}
}
func taskNetworkAttachment(id, name, driver string, addresses []string) func(*swarm.Task) {
return func(task *swarm.Task) {
task.NetworksAttachments = append(task.NetworksAttachments, swarm.NetworkAttachment{
Network: swarm.Network{
func taskNodeID(id string) func(*swarmtypes.Task) {
return func(task *swarmtypes.Task) {
task.NodeID = id
}
}
func taskNetworkAttachment(id, name, driver string, addresses []string) func(*swarmtypes.Task) {
return func(task *swarmtypes.Task) {
task.NetworksAttachments = append(task.NetworksAttachments, swarmtypes.NetworkAttachment{
Network: swarmtypes.Network{
ID: id,
Spec: swarm.NetworkSpec{
Annotations: swarm.Annotations{
Spec: swarmtypes.NetworkSpec{
Annotations: swarmtypes.Annotations{
Name: name,
},
DriverConfiguration: &swarm.Driver{
DriverConfiguration: &swarmtypes.Driver{
Name: driver,
},
},
@ -114,9 +111,9 @@ func taskNetworkAttachment(id, name, driver string, addresses []string) func(*sw
}
}
func taskStatus(ops ...func(*swarm.TaskStatus)) func(*swarm.Task) {
return func(task *swarm.Task) {
status := &swarm.TaskStatus{}
func taskStatus(ops ...func(*swarmtypes.TaskStatus)) func(*swarmtypes.Task) {
return func(task *swarmtypes.Task) {
status := &swarmtypes.TaskStatus{}
for _, op := range ops {
op(status)
@ -126,25 +123,25 @@ func taskStatus(ops ...func(*swarm.TaskStatus)) func(*swarm.Task) {
}
}
func taskState(state swarm.TaskState) func(*swarm.TaskStatus) {
return func(status *swarm.TaskStatus) {
func taskState(state swarmtypes.TaskState) func(*swarmtypes.TaskStatus) {
return func(status *swarmtypes.TaskStatus) {
status.State = state
}
}
func taskContainerStatus(id string) func(*swarm.TaskStatus) {
return func(status *swarm.TaskStatus) {
status.ContainerStatus = &swarm.ContainerStatus{
func taskContainerStatus(id string) func(*swarmtypes.TaskStatus) {
return func(status *swarmtypes.TaskStatus) {
status.ContainerStatus = &swarmtypes.ContainerStatus{
ContainerID: id,
}
}
}
func swarmService(ops ...func(*swarm.Service)) swarm.Service {
service := &swarm.Service{
func swarmService(ops ...func(*swarmtypes.Service)) swarmtypes.Service {
service := &swarmtypes.Service{
ID: "serviceID",
Spec: swarm.ServiceSpec{
Annotations: swarm.Annotations{
Spec: swarmtypes.ServiceSpec{
Annotations: swarmtypes.Annotations{
Name: "defaultServiceName",
},
},
@ -157,21 +154,21 @@ func swarmService(ops ...func(*swarm.Service)) swarm.Service {
return *service
}
func serviceName(name string) func(service *swarm.Service) {
return func(service *swarm.Service) {
func serviceName(name string) func(service *swarmtypes.Service) {
return func(service *swarmtypes.Service) {
service.Spec.Annotations.Name = name
}
}
func serviceLabels(labels map[string]string) func(service *swarm.Service) {
return func(service *swarm.Service) {
func serviceLabels(labels map[string]string) func(service *swarmtypes.Service) {
return func(service *swarmtypes.Service) {
service.Spec.Annotations.Labels = labels
}
}
func withEndpoint(ops ...func(*swarm.Endpoint)) func(*swarm.Service) {
return func(service *swarm.Service) {
endpoint := &swarm.Endpoint{}
func withEndpoint(ops ...func(*swarmtypes.Endpoint)) func(*swarmtypes.Service) {
return func(service *swarmtypes.Service) {
endpoint := &swarmtypes.Endpoint{}
for _, op := range ops {
op(endpoint)
@ -181,21 +178,21 @@ func withEndpoint(ops ...func(*swarm.Endpoint)) func(*swarm.Service) {
}
}
func virtualIP(networkID, addr string) func(*swarm.Endpoint) {
return func(endpoint *swarm.Endpoint) {
func virtualIP(networkID, addr string) func(*swarmtypes.Endpoint) {
return func(endpoint *swarmtypes.Endpoint) {
if endpoint.VirtualIPs == nil {
endpoint.VirtualIPs = []swarm.EndpointVirtualIP{}
endpoint.VirtualIPs = []swarmtypes.EndpointVirtualIP{}
}
endpoint.VirtualIPs = append(endpoint.VirtualIPs, swarm.EndpointVirtualIP{
endpoint.VirtualIPs = append(endpoint.VirtualIPs, swarmtypes.EndpointVirtualIP{
NetworkID: networkID,
Addr: addr,
})
}
}
func withEndpointSpec(ops ...func(*swarm.EndpointSpec)) func(*swarm.Service) {
return func(service *swarm.Service) {
endpointSpec := &swarm.EndpointSpec{}
func withEndpointSpec(ops ...func(*swarmtypes.EndpointSpec)) func(*swarmtypes.Service) {
return func(service *swarmtypes.Service) {
endpointSpec := &swarmtypes.EndpointSpec{}
for _, op := range ops {
op(endpointSpec)
@ -205,10 +202,10 @@ func withEndpointSpec(ops ...func(*swarm.EndpointSpec)) func(*swarm.Service) {
}
}
func modeDNSRR(spec *swarm.EndpointSpec) {
spec.Mode = swarm.ResolutionModeDNSRR
func modeDNSRR(spec *swarmtypes.EndpointSpec) {
spec.Mode = swarmtypes.ResolutionModeDNSRR
}
func modeVIP(spec *swarm.EndpointSpec) {
spec.Mode = swarm.ResolutionModeVIP
func modeVIP(spec *swarmtypes.EndpointSpec) {
spec.Mode = swarmtypes.ResolutionModeVIP
}

View file

@ -7,7 +7,7 @@ import (
"net"
"strings"
dockertypes "github.com/docker/docker/api/types"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/docker/go-connections/nat"
"github.com/rs/zerolog/log"
@ -114,7 +114,7 @@ func (p *DynConfBuilder) buildTCPServiceConfiguration(ctx context.Context, conta
}
}
if container.Health != "" && container.Health != dockertypes.Healthy {
if container.Health != "" && container.Health != containertypes.Healthy {
return nil
}
@ -138,7 +138,7 @@ func (p *DynConfBuilder) buildUDPServiceConfiguration(ctx context.Context, conta
}
}
if container.Health != "" && container.Health != dockertypes.Healthy {
if container.Health != "" && container.Health != containertypes.Healthy {
return nil
}
@ -164,7 +164,7 @@ func (p *DynConfBuilder) buildServiceConfiguration(ctx context.Context, containe
}
}
if container.Health != "" && container.Health != dockertypes.Healthy {
if container.Health != "" && container.Health != containertypes.Healthy {
return nil
}
@ -196,7 +196,7 @@ func (p *DynConfBuilder) keepContainer(ctx context.Context, container dockerData
return false
}
if !p.AllowEmptyServices && container.Health != "" && container.Health != dockertypes.Healthy {
if !p.AllowEmptyServices && container.Health != "" && container.Health != containertypes.Healthy {
logger.Debug().Msg("Filtering unhealthy or starting container")
return false
}
@ -344,8 +344,8 @@ func (p *DynConfBuilder) getIPAddress(ctx context.Context, container dockerData)
}
if container.NetworkSettings.NetworkMode.IsHost() {
if container.Node != nil && container.Node.IPAddress != "" {
return container.Node.IPAddress
if container.NodeIP != "" {
return container.NodeIP
}
if host, err := net.LookupHost("host.docker.internal"); err == nil {
return host[0]

View file

@ -5,9 +5,9 @@ import (
"testing"
"time"
docker "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/swarm"
containertypes "github.com/docker/docker/api/types/container"
networktypes "github.com/docker/docker/api/types/network"
swarmtypes "github.com/docker/docker/api/types/swarm"
"github.com/docker/go-connections/nat"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -2746,7 +2746,7 @@ func TestDynConfBuilder_build(t *testing.T) {
{
ServiceName: "Test",
Name: "Test",
Health: docker.Unhealthy,
Health: containertypes.Unhealthy,
},
},
expected: &dynamic.Configuration{
@ -2778,7 +2778,7 @@ func TestDynConfBuilder_build(t *testing.T) {
{
ServiceName: "Test",
Name: "Test",
Health: docker.Unhealthy,
Health: containertypes.Unhealthy,
},
},
expected: &dynamic.Configuration{
@ -2825,7 +2825,7 @@ func TestDynConfBuilder_build(t *testing.T) {
{
ServiceName: "Test",
Name: "Test",
Health: docker.Unhealthy,
Health: containertypes.Unhealthy,
Labels: map[string]string{
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
},
@ -2860,7 +2860,7 @@ func TestDynConfBuilder_build(t *testing.T) {
{
ServiceName: "Test",
Name: "Test",
Health: docker.Unhealthy,
Health: containertypes.Unhealthy,
Labels: map[string]string{
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
},
@ -2903,7 +2903,7 @@ func TestDynConfBuilder_build(t *testing.T) {
{
ServiceName: "Test",
Name: "Test",
Health: docker.Unhealthy,
Health: containertypes.Unhealthy,
Labels: map[string]string{
"traefik.udp.routers.foo": "true",
},
@ -2941,7 +2941,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Labels: map[string]string{
"traefik.udp.routers.foo": "true",
},
Health: docker.Unhealthy,
Health: containertypes.Unhealthy,
},
},
expected: &dynamic.Configuration{
@ -3944,7 +3944,7 @@ func TestDynConfBuilder_getIPPort_docker(t *testing.T) {
testCases := []struct {
desc string
container docker.ContainerJSON
container containertypes.InspectResponse
serverPort string
expected expected
}{
@ -4115,8 +4115,9 @@ func TestDynConfBuilder_getIPPort_docker(t *testing.T) {
func TestDynConfBuilder_getIPAddress_docker(t *testing.T) {
testCases := []struct {
desc string
container docker.ContainerJSON
container containertypes.InspectResponse
network string
nodeIP string
expected string
}{
{
@ -4192,10 +4193,10 @@ func TestDynConfBuilder_getIPAddress_docker(t *testing.T) {
expected: "127.0.0.1",
},
{
desc: "no network, no network label, mode host, node IP",
desc: "no network, no network label, mode host, node IP",
nodeIP: "10.0.0.5",
container: containerJSON(
networkMode("host"),
nodeIP("10.0.0.5"),
),
expected: "10.0.0.5",
},
@ -4210,6 +4211,9 @@ func TestDynConfBuilder_getIPAddress_docker(t *testing.T) {
}
dData := parseContainer(test.container)
if test.nodeIP != "" {
dData.NodeIP = test.nodeIP
}
dData.ExtraConf.Network = conf.Network
if len(test.network) > 0 {
@ -4226,14 +4230,14 @@ func TestDynConfBuilder_getIPAddress_docker(t *testing.T) {
func TestDynConfBuilder_getIPAddress_swarm(t *testing.T) {
testCases := []struct {
service swarm.Service
service swarmtypes.Service
expected string
networks map[string]*network.Summary
networks map[string]*networktypes.Summary
}{
{
service: swarmService(withEndpointSpec(modeDNSRR)),
expected: "",
networks: map[string]*network.Summary{},
networks: map[string]*networktypes.Summary{},
},
{
service: swarmService(
@ -4241,7 +4245,7 @@ func TestDynConfBuilder_getIPAddress_swarm(t *testing.T) {
withEndpoint(virtualIP("1", "10.11.12.13/24")),
),
expected: "10.11.12.13",
networks: map[string]*network.Summary{
networks: map[string]*networktypes.Summary{
"1": {
Name: "foo",
},
@ -4259,7 +4263,7 @@ func TestDynConfBuilder_getIPAddress_swarm(t *testing.T) {
),
),
expected: "10.11.12.99",
networks: map[string]*network.Summary{
networks: map[string]*networktypes.Summary{
"1": {
Name: "foonet",
},

View file

@ -1,8 +1,7 @@
package docker
import (
dockertypes "github.com/docker/docker/api/types"
dockercontainertypes "github.com/docker/docker/api/types/container"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat"
)
@ -14,13 +13,13 @@ type dockerData struct {
Labels map[string]string // List of labels set to container or service
NetworkSettings networkSettings
Health string
Node *dockertypes.ContainerNode
NodeIP string // Only filled in Swarm mode.
ExtraConf configuration
}
// NetworkSettings holds the networks data to the provider.
type networkSettings struct {
NetworkMode dockercontainertypes.NetworkMode
NetworkMode containertypes.NetworkMode
Ports nat.PortMap
Networks map[string]*networkData
}

View file

@ -9,7 +9,6 @@ import (
"time"
"github.com/cenkalti/backoff/v4"
dockertypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
eventtypes "github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
@ -104,7 +103,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
if p.Watch {
f := filters.NewArgs()
f.Add("type", "container")
options := dockertypes.EventsOptions{
options := eventtypes.ListOptions{
Filters: f,
}

View file

@ -8,8 +8,8 @@ import (
"time"
"github.com/cenkalti/backoff/v4"
dockertypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
networktypes "github.com/docker/docker/api/types/network"
swarmtypes "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/client"
@ -161,7 +161,7 @@ func (p *SwarmProvider) Provide(configurationChan chan<- dynamic.Message, pool *
func (p *SwarmProvider) listServices(ctx context.Context, dockerClient client.APIClient) ([]dockerData, error) {
logger := log.Ctx(ctx)
serviceList, err := dockerClient.ServiceList(ctx, dockertypes.ServiceListOptions{})
serviceList, err := dockerClient.ServiceList(ctx, swarmtypes.ServiceListOptions{})
if err != nil {
return nil, err
}
@ -179,13 +179,13 @@ func (p *SwarmProvider) listServices(ctx context.Context, dockerClient client.AP
networkListArgs.Add("driver", "overlay")
}
networkList, err := dockerClient.NetworkList(ctx, dockertypes.NetworkListOptions{Filters: networkListArgs})
networkList, err := dockerClient.NetworkList(ctx, networktypes.ListOptions{Filters: networkListArgs})
if err != nil {
logger.Debug().Err(err).Msg("Failed to network inspect on client for docker")
return nil, err
}
networkMap := make(map[string]*dockertypes.NetworkResource)
networkMap := make(map[string]*networktypes.Summary)
for _, network := range networkList {
networkMap[network.ID] = &network
}
@ -218,7 +218,7 @@ func (p *SwarmProvider) listServices(ctx context.Context, dockerClient client.AP
return dockerDataList, err
}
func (p *SwarmProvider) parseService(ctx context.Context, service swarmtypes.Service, networkMap map[string]*dockertypes.NetworkResource) (dockerData, error) {
func (p *SwarmProvider) parseService(ctx context.Context, service swarmtypes.Service, networkMap map[string]*networktypes.Summary) (dockerData, error) {
logger := log.Ctx(ctx)
dData := dockerData{
@ -267,13 +267,13 @@ func (p *SwarmProvider) parseService(ctx context.Context, service swarmtypes.Ser
}
func listTasks(ctx context.Context, dockerClient client.APIClient, serviceID string,
serviceDockerData dockerData, networkMap map[string]*dockertypes.NetworkResource, isGlobalSvc bool,
serviceDockerData dockerData, networkMap map[string]*networktypes.Summary, isGlobalSvc bool,
) ([]dockerData, error) {
serviceIDFilter := filters.NewArgs()
serviceIDFilter.Add("service", serviceID)
serviceIDFilter.Add("desired-state", "running")
taskList, err := dockerClient.TaskList(ctx, dockertypes.TaskListOptions{Filters: serviceIDFilter})
taskList, err := dockerClient.TaskList(ctx, swarmtypes.TaskListOptions{Filters: serviceIDFilter})
if err != nil {
return nil, err
}
@ -283,7 +283,11 @@ func listTasks(ctx context.Context, dockerClient client.APIClient, serviceID str
if task.Status.State != swarmtypes.TaskStateRunning {
continue
}
dData := parseTasks(ctx, task, serviceDockerData, networkMap, isGlobalSvc)
dData, err := parseTasks(ctx, dockerClient, task, serviceDockerData, networkMap, isGlobalSvc)
if err != nil {
log.Ctx(ctx).Warn().Err(err).Msgf("Error while parsing task %s", getServiceName(dData))
continue
}
if len(dData.NetworkSettings.Networks) > 0 {
dockerDataList = append(dockerDataList, dData)
}
@ -291,9 +295,9 @@ func listTasks(ctx context.Context, dockerClient client.APIClient, serviceID str
return dockerDataList, err
}
func parseTasks(ctx context.Context, task swarmtypes.Task, serviceDockerData dockerData,
networkMap map[string]*dockertypes.NetworkResource, isGlobalSvc bool,
) dockerData {
func parseTasks(ctx context.Context, dockerClient client.APIClient, task swarmtypes.Task, serviceDockerData dockerData,
networkMap map[string]*networktypes.Summary, isGlobalSvc bool,
) (dockerData, error) {
dData := dockerData{
ID: task.ID,
ServiceName: serviceDockerData.Name,
@ -307,6 +311,14 @@ func parseTasks(ctx context.Context, task swarmtypes.Task, serviceDockerData doc
dData.Name = serviceDockerData.Name + "." + task.ID
}
if task.NodeID != "" {
node, _, err := dockerClient.NodeInspectWithRaw(ctx, task.NodeID)
if err != nil {
return dockerData{}, fmt.Errorf("inspecting node %s: %w", task.NodeID, err)
}
dData.NodeIP = node.Status.Addr
}
if task.NetworksAttachments != nil {
dData.NetworkSettings.Networks = make(map[string]*networkData)
for _, virtualIP := range task.NetworksAttachments {
@ -328,5 +340,5 @@ func parseTasks(ctx context.Context, task swarmtypes.Task, serviceDockerData doc
}
}
}
return dData
return dData, nil
}

View file

@ -4,35 +4,47 @@ import (
"context"
dockertypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
containertypes "github.com/docker/docker/api/types/container"
networktypes "github.com/docker/docker/api/types/network"
swarmtypes "github.com/docker/docker/api/types/swarm"
dockerclient "github.com/docker/docker/client"
)
type fakeTasksClient struct {
dockerclient.APIClient
tasks []swarm.Task
container dockertypes.ContainerJSON
tasks []swarmtypes.Task
container containertypes.InspectResponse
err error
}
func (c *fakeTasksClient) TaskList(ctx context.Context, options dockertypes.TaskListOptions) ([]swarm.Task, error) {
func (c *fakeTasksClient) TaskList(ctx context.Context, options swarmtypes.TaskListOptions) ([]swarmtypes.Task, error) {
return c.tasks, c.err
}
func (c *fakeTasksClient) ContainerInspect(ctx context.Context, container string) (dockertypes.ContainerJSON, error) {
func (c *fakeTasksClient) ContainerInspect(ctx context.Context, container string) (containertypes.InspectResponse, error) {
return c.container, c.err
}
type fakeServicesClient struct {
dockerclient.APIClient
dockerVersion string
networks []dockertypes.NetworkResource
services []swarm.Service
tasks []swarm.Task
networks []networktypes.Summary
nodes []swarmtypes.Node
services []swarmtypes.Service
tasks []swarmtypes.Task
err error
}
func (c *fakeServicesClient) ServiceList(ctx context.Context, options dockertypes.ServiceListOptions) ([]swarm.Service, error) {
func (c *fakeServicesClient) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarmtypes.Node, []byte, error) {
for _, node := range c.nodes {
if node.ID == nodeID {
return node, nil, nil
}
}
return swarmtypes.Node{}, nil, c.err
}
func (c *fakeServicesClient) ServiceList(ctx context.Context, options swarmtypes.ServiceListOptions) ([]swarmtypes.Service, error) {
return c.services, c.err
}
@ -40,10 +52,10 @@ func (c *fakeServicesClient) ServerVersion(ctx context.Context) (dockertypes.Ver
return dockertypes.Version{APIVersion: c.dockerVersion}, c.err
}
func (c *fakeServicesClient) NetworkList(ctx context.Context, options dockertypes.NetworkListOptions) ([]dockertypes.NetworkResource, error) {
func (c *fakeServicesClient) NetworkList(ctx context.Context, options networktypes.ListOptions) ([]networktypes.Summary, error) {
return c.networks, c.err
}
func (c *fakeServicesClient) TaskList(ctx context.Context, options dockertypes.TaskListOptions) ([]swarm.Task, error) {
func (c *fakeServicesClient) TaskList(ctx context.Context, options swarmtypes.TaskListOptions) ([]swarmtypes.Task, error) {
return c.tasks, c.err
}

View file

@ -5,32 +5,32 @@ import (
"testing"
"time"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/swarm"
networktypes "github.com/docker/docker/api/types/network"
swarmtypes "github.com/docker/docker/api/types/swarm"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestListTasks(t *testing.T) {
testCases := []struct {
service swarm.Service
tasks []swarm.Task
service swarmtypes.Service
tasks []swarmtypes.Task
isGlobalSVC bool
expectedTasks []string
networks map[string]*network.Summary
networks map[string]*networktypes.Summary
}{
{
service: swarmService(serviceName("container")),
tasks: []swarm.Task{
tasks: []swarmtypes.Task{
swarmTask("id1",
taskSlot(1),
taskNetworkAttachment("1", "network1", "overlay", []string{"127.0.0.1"}),
taskStatus(taskState(swarm.TaskStateRunning)),
taskStatus(taskState(swarmtypes.TaskStateRunning)),
),
swarmTask("id2",
taskSlot(2),
taskNetworkAttachment("1", "network1", "overlay", []string{"127.0.0.2"}),
taskStatus(taskState(swarm.TaskStatePending)),
taskStatus(taskState(swarmtypes.TaskStatePending)),
),
swarmTask("id3",
taskSlot(3),
@ -39,12 +39,12 @@ func TestListTasks(t *testing.T) {
swarmTask("id4",
taskSlot(4),
taskNetworkAttachment("1", "network1", "overlay", []string{"127.0.0.4"}),
taskStatus(taskState(swarm.TaskStateRunning)),
taskStatus(taskState(swarmtypes.TaskStateRunning)),
),
swarmTask("id5",
taskSlot(5),
taskNetworkAttachment("1", "network1", "overlay", []string{"127.0.0.5"}),
taskStatus(taskState(swarm.TaskStateFailed)),
taskStatus(taskState(swarmtypes.TaskStateFailed)),
),
},
isGlobalSVC: false,
@ -52,7 +52,7 @@ func TestListTasks(t *testing.T) {
"container.1",
"container.4",
},
networks: map[string]*network.Summary{
networks: map[string]*networktypes.Summary{
"1": {
Name: "foo",
},
@ -89,15 +89,15 @@ func TestListTasks(t *testing.T) {
func TestSwarmProvider_listServices(t *testing.T) {
testCases := []struct {
desc string
services []swarm.Service
tasks []swarm.Task
services []swarmtypes.Service
tasks []swarmtypes.Task
dockerVersion string
networks []network.Summary
networks []networktypes.Summary
expectedServices []string
}{
{
desc: "Should return no service due to no networks defined",
services: []swarm.Service{
services: []swarmtypes.Service{
swarmService(
serviceName("service1"),
serviceLabels(map[string]string{
@ -118,12 +118,12 @@ func TestSwarmProvider_listServices(t *testing.T) {
withEndpointSpec(modeDNSRR)),
},
dockerVersion: "1.30",
networks: []network.Summary{},
networks: []networktypes.Summary{},
expectedServices: []string{},
},
{
desc: "Should return only service1",
services: []swarm.Service{
services: []swarmtypes.Service{
swarmService(
serviceName("service1"),
serviceLabels(map[string]string{
@ -144,7 +144,7 @@ func TestSwarmProvider_listServices(t *testing.T) {
withEndpointSpec(modeDNSRR)),
},
dockerVersion: "1.30",
networks: []network.Summary{
networks: []networktypes.Summary{
{
Name: "network_name",
ID: "yk6l57rfwizjzxxzftn4amaot",
@ -156,8 +156,8 @@ func TestSwarmProvider_listServices(t *testing.T) {
Ingress: false,
ConfigOnly: false,
Options: map[string]string{
"com.docker.network.driver.overlay.vxlanid_list": "4098",
"com.docker.network.enable_ipv6": "false",
"com.docker.networktypes.driver.overlay.vxlanid_list": "4098",
"com.docker.networktypes.enable_ipv6": "false",
},
Labels: map[string]string{
"com.docker.stack.namespace": "test",
@ -170,7 +170,7 @@ func TestSwarmProvider_listServices(t *testing.T) {
},
{
desc: "Should return service1 and service2",
services: []swarm.Service{
services: []swarmtypes.Service{
swarmService(
serviceName("service1"),
serviceLabels(map[string]string{
@ -188,18 +188,18 @@ func TestSwarmProvider_listServices(t *testing.T) {
}),
withEndpointSpec(modeDNSRR)),
},
tasks: []swarm.Task{
tasks: []swarmtypes.Task{
swarmTask("id1",
taskNetworkAttachment("yk6l57rfwizjzxxzftn4amaot", "network_name", "overlay", []string{"127.0.0.1"}),
taskStatus(taskState(swarm.TaskStateRunning)),
taskStatus(taskState(swarmtypes.TaskStateRunning)),
),
swarmTask("id2",
taskNetworkAttachment("yk6l57rfwizjzxxzftn4amaot", "network_name", "overlay", []string{"127.0.0.1"}),
taskStatus(taskState(swarm.TaskStateRunning)),
taskStatus(taskState(swarmtypes.TaskStateRunning)),
),
},
dockerVersion: "1.30",
networks: []network.Summary{
networks: []networktypes.Summary{
{
Name: "network_name",
ID: "yk6l57rfwizjzxxzftn4amaot",
@ -211,8 +211,8 @@ func TestSwarmProvider_listServices(t *testing.T) {
Ingress: false,
ConfigOnly: false,
Options: map[string]string{
"com.docker.network.driver.overlay.vxlanid_list": "4098",
"com.docker.network.enable_ipv6": "false",
"com.docker.networktypes.driver.overlay.vxlanid_list": "4098",
"com.docker.networktypes.enable_ipv6": "false",
},
Labels: map[string]string{
"com.docker.stack.namespace": "test",
@ -253,15 +253,16 @@ func TestSwarmProvider_listServices(t *testing.T) {
func TestSwarmProvider_parseService_task(t *testing.T) {
testCases := []struct {
service swarm.Service
tasks []swarm.Task
service swarmtypes.Service
tasks []swarmtypes.Task
nodes []swarmtypes.Node
isGlobalSVC bool
expected map[string]dockerData
networks map[string]*network.Summary
networks map[string]*networktypes.Summary
}{
{
service: swarmService(serviceName("container")),
tasks: []swarm.Task{
tasks: []swarmtypes.Task{
swarmTask("id1", taskSlot(1)),
swarmTask("id2", taskSlot(2)),
swarmTask("id3", taskSlot(3)),
@ -278,7 +279,7 @@ func TestSwarmProvider_parseService_task(t *testing.T) {
Name: "container.3",
},
},
networks: map[string]*network.Summary{
networks: map[string]*networktypes.Summary{
"1": {
Name: "foo",
},
@ -286,7 +287,7 @@ func TestSwarmProvider_parseService_task(t *testing.T) {
},
{
service: swarmService(serviceName("container")),
tasks: []swarm.Task{
tasks: []swarmtypes.Task{
swarmTask("id1"),
swarmTask("id2"),
swarmTask("id3"),
@ -303,7 +304,7 @@ func TestSwarmProvider_parseService_task(t *testing.T) {
Name: "container.id3",
},
},
networks: map[string]*network.Summary{
networks: map[string]*networktypes.Summary{
"1": {
Name: "foo",
},
@ -317,12 +318,12 @@ func TestSwarmProvider_parseService_task(t *testing.T) {
virtualIP("1", ""),
),
),
tasks: []swarm.Task{
tasks: []swarmtypes.Task{
swarmTask(
"id1",
taskNetworkAttachment("1", "vlan", "macvlan", []string{"127.0.0.1"}),
taskStatus(
taskState(swarm.TaskStateRunning),
taskState(swarmtypes.TaskStateRunning),
taskContainerStatus("c1"),
),
),
@ -341,12 +342,39 @@ func TestSwarmProvider_parseService_task(t *testing.T) {
},
},
},
networks: map[string]*network.Summary{
networks: map[string]*networktypes.Summary{
"1": {
Name: "vlan",
},
},
},
{
service: swarmService(serviceName("container")),
tasks: []swarmtypes.Task{
swarmTask("id1",
taskSlot(1),
taskNodeID("id1"),
),
},
nodes: []swarmtypes.Node{
{
Status: swarmtypes.NodeStatus{
Addr: "10.11.12.13",
},
},
},
expected: map[string]dockerData{
"id1": {
Name: "container.1",
NodeIP: "10.11.12.13",
},
},
networks: map[string]*networktypes.Summary{
"1": {
Name: "foo",
},
},
},
}
for caseID, test := range testCases {
@ -359,8 +387,12 @@ func TestSwarmProvider_parseService_task(t *testing.T) {
dData, err := p.parseService(t.Context(), test.service, test.networks)
require.NoError(t, err)
dockerClient := &fakeServicesClient{tasks: test.tasks}
for _, task := range test.tasks {
taskDockerData := parseTasks(t.Context(), task, dData, test.networks, test.isGlobalSVC)
taskDockerData, err := parseTasks(t.Context(), dockerClient, task, dData, test.networks, test.isGlobalSVC)
require.NoError(t, err)
expected := test.expected[task.ID]
assert.Equal(t, expected.Name, taskDockerData.Name)
}

View file

@ -9,7 +9,7 @@ import (
"time"
"github.com/docker/cli/cli/connhelper"
dockertypes "github.com/docker/docker/api/types"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/docker/go-connections/nat"
"github.com/docker/go-connections/sockets"
@ -52,7 +52,7 @@ func inspectContainers(ctx context.Context, dockerClient client.ContainerAPIClie
return dockerData{}
}
func parseContainer(container dockertypes.ContainerJSON) dockerData {
func parseContainer(container containertypes.InspectResponse) dockerData {
dData := dockerData{
NetworkSettings: networkSettings{},
}
@ -61,7 +61,6 @@ func parseContainer(container dockertypes.ContainerJSON) dockerData {
dData.ID = container.ContainerJSONBase.ID
dData.Name = container.ContainerJSONBase.Name
dData.ServiceName = dData.Name // Default ServiceName to be the container's Name.
dData.Node = container.ContainerJSONBase.Node
if container.ContainerJSONBase.HostConfig != nil {
dData.NetworkSettings.NetworkMode = container.ContainerJSONBase.HostConfig.NetworkMode

View file

@ -4,8 +4,9 @@ import (
"strconv"
"testing"
docker "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
containertypes "github.com/docker/docker/api/types/container"
networktypes "github.com/docker/docker/api/types/network"
swarmtypes "github.com/docker/docker/api/types/swarm"
"github.com/docker/go-connections/nat"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -14,7 +15,7 @@ import (
func Test_getPort_docker(t *testing.T) {
testCases := []struct {
desc string
container docker.ContainerJSON
container containertypes.InspectResponse
serverPort string
expected string
}{
@ -78,16 +79,16 @@ func Test_getPort_docker(t *testing.T) {
func Test_getPort_swarm(t *testing.T) {
testCases := []struct {
service swarm.Service
service swarmtypes.Service
serverPort string
networks map[string]*docker.NetworkResource
networks map[string]*networktypes.Summary
expected string
}{
{
service: swarmService(
withEndpointSpec(modeDNSRR),
),
networks: map[string]*docker.NetworkResource{},
networks: map[string]*networktypes.Summary{},
serverPort: "8080",
expected: "8080",
},