diff --git a/provider/docker/docker.go b/provider/docker/docker.go index 12f7f9127..a56823065 100644 --- a/provider/docker/docker.go +++ b/provider/docker/docker.go @@ -777,19 +777,21 @@ func listServices(ctx context.Context, dockerClient client.APIClient) ([]dockerD for _, service := range serviceList { dockerData := parseService(service, networkMap) - if len(dockerData.NetworkSettings.Networks) > 0 { - useSwarmLB, _ := strconv.ParseBool(getIsBackendLBSwarm(dockerData)) - if useSwarmLB { + useSwarmLB, _ := strconv.ParseBool(getIsBackendLBSwarm(dockerData)) + + if useSwarmLB { + if len(dockerData.NetworkSettings.Networks) > 0 { dockerDataList = append(dockerDataList, dockerData) - } else { - isGlobalSvc := service.Spec.Mode.Global != nil - dockerDataListTasks, err = listTasks(ctx, dockerClient, service.ID, dockerData, networkMap, isGlobalSvc) - - for _, dockerDataTask := range dockerDataListTasks { - dockerDataList = append(dockerDataList, dockerDataTask) - } } + } else { + isGlobalSvc := service.Spec.Mode.Global != nil + dockerDataListTasks, err = listTasks(ctx, dockerClient, service.ID, dockerData, networkMap, isGlobalSvc) + + for _, dockerDataTask := range dockerDataListTasks { + dockerDataList = append(dockerDataList, dockerDataTask) + } + } } return dockerDataList, err @@ -805,7 +807,10 @@ func parseService(service swarmtypes.Service, networkMap map[string]*dockertypes if service.Spec.EndpointSpec != nil { if service.Spec.EndpointSpec.Mode == swarmtypes.ResolutionModeDNSRR { - log.Warnf("Ignored endpoint-mode not supported, service name: %s", service.Spec.Annotations.Name) + useSwarmLB, _ := strconv.ParseBool(getIsBackendLBSwarm(dockerData)) + if useSwarmLB { + log.Warnf("Ignored %s endpoint-mode not supported, service name: %s. Fallback to Træfik load balancing", swarmtypes.ResolutionModeDNSRR, service.Spec.Annotations.Name) + } } else if service.Spec.EndpointSpec.Mode == swarmtypes.ResolutionModeVIP { dockerData.NetworkSettings.Networks = make(map[string]*networkData) for _, virtualIP := range service.Endpoint.VirtualIPs { diff --git a/provider/docker/swarm_test.go b/provider/docker/swarm_test.go index 2ff0aaee9..e0fe058e5 100644 --- a/provider/docker/swarm_test.go +++ b/provider/docker/swarm_test.go @@ -773,6 +773,7 @@ type fakeServicesClient struct { dockerVersion string networks []dockertypes.NetworkResource services []swarm.Service + tasks []swarm.Task err error } @@ -788,10 +789,15 @@ func (c *fakeServicesClient) NetworkList(ctx context.Context, options dockertype return c.networks, c.err } +func (c *fakeServicesClient) TaskList(ctx context.Context, options dockertypes.TaskListOptions) ([]swarm.Task, error) { + return c.tasks, c.err +} + func TestListServices(t *testing.T) { testCases := []struct { desc string services []swarm.Service + tasks []swarm.Task dockerVersion string networks []dockertypes.NetworkResource expectedServices []string @@ -813,7 +819,8 @@ func TestListServices(t *testing.T) { swarmService( serviceName("service2"), serviceLabels(map[string]string{ - labelDockerNetwork: "barnet", + labelDockerNetwork: "barnet", + labelBackendLoadBalancerSwarm: "true", }), withEndpointSpec(modeDNSSR)), }, @@ -838,7 +845,8 @@ func TestListServices(t *testing.T) { swarmService( serviceName("service2"), serviceLabels(map[string]string{ - labelDockerNetwork: "barnet", + labelDockerNetwork: "barnet", + labelBackendLoadBalancerSwarm: "true", }), withEndpointSpec(modeDNSSR)), }, @@ -867,13 +875,65 @@ func TestListServices(t *testing.T) { "service1", }, }, + { + desc: "Should return service1 and service2", + services: []swarm.Service{ + swarmService( + serviceName("service1"), + serviceLabels(map[string]string{ + labelDockerNetwork: "barnet", + }), + withEndpointSpec(modeVIP), + withEndpoint( + virtualIP("yk6l57rfwizjzxxzftn4amaot", "10.11.12.13/24"), + virtualIP("2", "10.11.12.99/24"), + )), + swarmService( + serviceName("service2"), + serviceLabels(map[string]string{ + labelDockerNetwork: "barnet", + }), + withEndpointSpec(modeDNSSR)), + }, + tasks: []swarm.Task{ + swarmTask("id1", taskStatus(taskState(swarm.TaskStateRunning))), + swarmTask("id2", taskStatus(taskState(swarm.TaskStateRunning))), + }, + dockerVersion: "1.30", + networks: []dockertypes.NetworkResource{ + { + Name: "network_name", + ID: "yk6l57rfwizjzxxzftn4amaot", + Created: time.Now(), + Scope: "swarm", + Driver: "overlay", + EnableIPv6: false, + Internal: true, + Ingress: false, + ConfigOnly: false, + Options: map[string]string{ + "com.docker.network.driver.overlay.vxlanid_list": "4098", + "com.docker.network.enable_ipv6": "false", + }, + Labels: map[string]string{ + "com.docker.stack.namespace": "test", + }, + }, + }, + expectedServices: []string{ + "service1.0", + "service1.0", + "service2.0", + "service2.0", + }, + }, } for caseID, test := range testCases { test := test t.Run(strconv.Itoa(caseID), func(t *testing.T) { t.Parallel() - dockerClient := &fakeServicesClient{services: test.services, dockerVersion: test.dockerVersion, networks: test.networks} + dockerClient := &fakeServicesClient{services: test.services, tasks: test.tasks, dockerVersion: test.dockerVersion, networks: test.networks} serviceDockerData, _ := listServices(context.Background(), dockerClient) assert.Equal(t, len(test.expectedServices), len(serviceDockerData))