-
Notifications
You must be signed in to change notification settings - Fork 5
/
matcher.go
108 lines (90 loc) · 2.17 KB
/
matcher.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
102
103
104
105
106
107
108
package cachecluster
import (
"context"
"net"
"cloud.google.com/go/compute/metadata"
"golang.org/x/oauth2/google"
"google.golang.org/api/compute/v1"
)
type (
matcher struct {
service *compute.Service
config *MatchConfig
}
)
func newMatcher(config *MatchConfig) (*matcher, error) {
ctx := context.Background()
hc, err := google.DefaultClient(ctx, compute.ComputeReadonlyScope)
config.Project, err = metadata.ProjectID()
config.Zone, err = metadata.Zone()
service, err := compute.New(hc)
if err != nil {
return nil, err
}
im := matcher{
config: config,
service: service,
}
return &im, nil
}
func (m *matcher) getIPAddresses(ctx context.Context) ([]net.IP, error) {
instances, err := m.getInstances(ctx)
if err != nil {
return nil, err
}
results := make([]net.IP, 0, len(instances))
for _, instance := range instances {
for _, nic := range instance.NetworkInterfaces {
if nic.Name == m.config.NetworkInterface || len(instance.NetworkInterfaces) == 1 {
ip := net.ParseIP(nic.NetworkIP)
results = append(results, ip)
}
}
}
return results, nil
}
func (m *matcher) getInstances(ctx context.Context) ([]*compute.Instance, error) {
results := make([]*compute.Instance, 0)
logger.Debugf("list instances in %s / %s", m.config.Project, m.config.Zone)
req := m.service.Instances.List(m.config.Project, m.config.Zone)
req.Filter("status eq RUNNING")
if err := req.Pages(ctx, func(page *compute.InstanceList) error {
for _, instance := range page.Items {
if m.matchesConfig(instance) {
logger.Debugf("found %s", instance.Name)
results = append(results, instance)
}
}
return nil
}); err != nil {
return nil, err
}
return results, nil
}
func (m *matcher) matchesConfig(instance *compute.Instance) bool {
for _, tag := range m.config.Tags {
found := false
for _, itag := range instance.Tags.Items {
if tag == itag {
found = true
break
}
}
if !found {
return false
}
}
for k, v := range m.config.Meta {
found := false
for _, imeta := range instance.Metadata.Items {
if k == imeta.Key && v == *imeta.Value {
found = true
break
}
}
if !found {
return false
}
}
return true
}