-
Notifications
You must be signed in to change notification settings - Fork 6
/
docker.go
86 lines (74 loc) · 1.89 KB
/
docker.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
package main
import (
"net/netip"
docker "github.com/fsouza/go-dockerclient"
"go.uber.org/zap"
"go4.org/netipx"
)
var (
dockerLogger = logger.Named("Docker")
dockerNetworks []string
dockerClient *docker.Client
dockerNetIPSets = map[string]*netipx.IPSet{}
dockerActiveIPs = &netipx.IPSet{}
dockerNewIP = make(chan netip.Addr, 64)
)
func dockerListen() (e error) {
if dockerClient, e = docker.NewClientFromEnv(); e != nil {
return e
}
events := make(chan *docker.APIEvents, 64)
if e = dockerClient.AddEventListenerWithOptions(docker.EventsOptions{
Filters: map[string][]string{
"type": {"network"},
"event": {"connect", "disconnect"},
"network": dockerNetworks,
},
}, events); e != nil {
return e
}
for _, network := range dockerNetworks {
dockerRefreshNetwork(network, func(string) bool { return true })
}
go func() {
for evt := range events {
ctID := evt.Actor.Attributes["container"]
dockerRefreshNetwork(evt.Actor.Attributes["name"],
func(ct string) bool { return ct == ctID })
}
}()
return nil
}
func dockerRefreshNetwork(name string, isNewContainer func(ctID string) bool) {
network, e := dockerClient.NetworkInfo(name)
if e != nil {
dockerLogger.Warn("NetworkInfo error", zap.Error(e))
return
}
var b netipx.IPSetBuilder
var ipAddrs []string
var newIPs []netip.Addr
for ctID, ct := range network.Containers {
prefix, _ := netip.ParsePrefix(ct.IPv6Address)
ip := prefix.Addr()
b.Add(ip)
ipAddrs = append(ipAddrs, ip.String())
if isNewContainer(ctID) {
newIPs = append(newIPs, ip)
}
}
dockerLogger.Info("active IPs updated",
zap.String("network", network.Name),
zap.Strings("ip", ipAddrs),
)
dockerNetIPSets[network.ID], _ = b.IPSet()
for net, ipset := range dockerNetIPSets {
if net != network.ID {
b.AddSet(ipset)
}
}
dockerActiveIPs, _ = b.IPSet()
for _, ip := range newIPs {
dockerNewIP <- ip
}
}