-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathsync.go
89 lines (78 loc) · 2.21 KB
/
sync.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
package whalewall
import (
"context"
"fmt"
"slices"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"go.uber.org/zap"
"gopkg.in/yaml.v3"
)
const composeDependsLabel = "com.docker.compose.depends_on"
func (r *RuleManager) syncContainers(ctx context.Context) error {
filter := filters.NewArgs(filters.KeyValuePair{
Key: "label",
Value: enabledLabel,
})
containers, err := r.dockerCli.ContainerList(ctx, types.ContainerListOptions{Filters: filter})
if err != nil {
return fmt.Errorf("error listing containers: %w", err)
}
// sort containers so those that don't have dependencies go first
slices.SortFunc(containers, func(a, b types.Container) int {
_, aHasLabels := a.Labels[composeDependsLabel]
_, bHasLabels := b.Labels[composeDependsLabel]
if aHasLabels == bHasLabels {
return 0
} else if !aHasLabels && bHasLabels {
return -1
}
return 1
})
for _, c := range containers {
truncID := c.ID[:12]
container, err := r.dockerCli.ContainerInspect(ctx, c.ID)
if err != nil {
r.logger.Error("error inspecting container", zap.String("container.id", truncID), zap.Error(err))
continue
}
exists, err := r.containerExists(ctx, r.db, c.ID)
if err != nil {
r.logger.Error("error querying container from database", zap.String("container.id", truncID), zap.Error(err))
continue
}
if exists {
// we are aware of the container and have created rules for
// it before, but the rules could have been deleted since
// then so recreate any missing rules
r.createCh <- containerDetails{
container: container,
isNew: false,
}
continue
}
enabled, err := whalewallEnabled(container.Config.Labels)
if err != nil {
r.logger.Error("error parsing label", zap.String("container.id", truncID), zap.String("label", enabledLabel), zap.Error(err))
continue
}
if enabled {
r.createCh <- containerDetails{
container: container,
isNew: true,
}
}
}
return nil
}
func whalewallEnabled(labels map[string]string) (bool, error) {
e, ok := labels[enabledLabel]
if !ok {
return false, nil
}
var enabled bool
if err := yaml.Unmarshal([]byte(e), &enabled); err != nil {
return false, err
}
return enabled, nil
}