-
Notifications
You must be signed in to change notification settings - Fork 168
/
services.go
101 lines (79 loc) · 3.05 KB
/
services.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package generator
import (
"context"
"net"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/swarm"
"github.com/lucaslorentz/caddy-docker-proxy/v2/caddyfile"
"go.uber.org/zap"
)
func (g *CaddyfileGenerator) getServiceCaddyfile(service *swarm.Service, logger *zap.Logger) (*caddyfile.Container, error) {
caddyLabels := g.filterLabels(service.Spec.Labels)
return labelsToCaddyfile(caddyLabels, service, func() ([]string, error) {
return g.getServiceProxyTargets(service, logger, true)
})
}
func (g *CaddyfileGenerator) getServiceProxyTargets(service *swarm.Service, logger *zap.Logger, onlyIngressIps bool) ([]string, error) {
if g.options.ProxyServiceTasks {
return g.getServiceTasksIps(service, logger, onlyIngressIps)
}
_, err := g.getServiceVirtualIps(service, logger, onlyIngressIps)
if err != nil {
return nil, err
}
return []string{service.Spec.Name}, nil
}
func (g *CaddyfileGenerator) getServiceVirtualIps(service *swarm.Service, logger *zap.Logger, onlyIngressIps bool) ([]string, error) {
virtualIps := []string{}
for _, virtualIP := range service.Endpoint.VirtualIPs {
if !onlyIngressIps || g.ingressNetworks[virtualIP.NetworkID] {
virtualIps = append(virtualIps, virtualIP.Addr)
}
}
if len(virtualIps) == 0 {
logger.Warn("Service is not in same network as caddy", zap.String("service", service.Spec.Name), zap.String("serviceId", service.ID))
}
return virtualIps, nil
}
func (g *CaddyfileGenerator) getServiceTasksIps(service *swarm.Service, logger *zap.Logger, onlyIngressIps bool) ([]string, error) {
taskListFilter := filters.NewArgs()
taskListFilter.Add("service", service.ID)
taskListFilter.Add("desired-state", "running")
hasRunningTasks := false
tasksIps := []string{}
for _, dockerClient := range g.dockerClients {
tasks, err := dockerClient.TaskList(context.Background(), types.TaskListOptions{Filters: taskListFilter})
if err != nil {
return []string{}, err
}
for _, task := range tasks {
if task.Status.State == swarm.TaskStateRunning {
hasRunningTasks = true
ingressNetworkFromLabel, overrideNetwork := service.Spec.Labels[IngressNetworkLabel]
for _, networkAttachment := range task.NetworksAttachments {
include := false
if !onlyIngressIps {
include = true
} else if overrideNetwork {
include = networkAttachment.Network.Spec.Name == ingressNetworkFromLabel
} else {
include = g.ingressNetworks[networkAttachment.Network.ID]
}
if include {
for _, address := range networkAttachment.Addresses {
ipAddress, _, _ := net.ParseCIDR(address)
tasksIps = append(tasksIps, ipAddress.String())
}
}
}
}
}
}
if !hasRunningTasks {
logger.Warn("Service has no tasks in running state", zap.String("service", service.Spec.Name), zap.String("serviceId", service.ID))
} else if len(tasksIps) == 0 {
logger.Warn("Service is not in same network as caddy", zap.String("service", service.Spec.Name), zap.String("serviceId", service.ID))
}
return tasksIps, nil
}