Skip to content

Commit 456eec4

Browse files
committed
feat(labels): add support for custom ranges for az and service labels
1 parent 46e4c30 commit 456eec4

File tree

4 files changed

+81
-12
lines changed

4 files changed

+81
-12
lines changed

Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@ RUN [[ $(ls -1 vendor/ | wc -l) -gt 0 ]] || (echo "Expected 'vendor' dependencie
1515
COPY cmd/ cmd/
1616
COPY pkg/ pkg/
1717

18+
COPY custom_ranges.json /etc/kubenetmon/custom_ranges.json
19+
1820
# Build
1921
ARG VERSION=dev
2022
ARG GIT_COMMIT=unspecified
2123
ARG TARGETOS TARGETARCH
2224
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -a -o bin/ ./...
25+
RUN CGO_ENABLED=1 GOOS=linux go test -v -race -coverprofile cover.out -tags '!integration' ./...
2326

2427
# Use distroless as minimal base image to package the kubenetmon binary
2528
# Refer to https://github.com/GoogleContainerTools/distroless for more details

pkg/labeler/public_ranges.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,23 @@ type AzurePrefixGroupProperties struct {
142142
NetworkFeatures []string `json:"networkFeatures"`
143143
}
144144

145+
/* Custom IP range structs */
146+
type CustomIPRanges struct {
147+
SyncToken string `json:"syncToken"`
148+
CreateDate string `json:"createDate"`
149+
Prefixes []CustomPrefix `json:"prefixes"`
150+
}
151+
type CustomPrefix struct {
152+
IPPrefixStr string `json:"ip_prefix"`
153+
AvailabilityZone string `json:"az"`
154+
Service string `json:"service"`
155+
}
156+
145157
type remoteIPPrefixDetail struct {
146158
cloud Cloud
147159
service string
148160
region string
161+
az string
149162
}
150163

151164
func (d *remoteIPPrefixDetail) Normalize() {
@@ -167,7 +180,7 @@ var awsServicePriorities map[string]int = map[string]int{
167180
"ec2": 2,
168181
}
169182

170-
func refreshRemoteIPs(aws AWSIPRanges, gcp GCPIPRanges, google GoogleIPRanges, azure AzureIPRanges) (map[ipaddr.IPv4AddressKey]remoteIPPrefixDetail, *ipaddr.IPv4AddressTrie, error) {
183+
func refreshRemoteIPs(aws AWSIPRanges, gcp GCPIPRanges, google GoogleIPRanges, azure AzureIPRanges, custom CustomIPRanges) (map[ipaddr.IPv4AddressKey]remoteIPPrefixDetail, *ipaddr.IPv4AddressTrie, error) {
171184
remoteIPRanges := make(map[ipaddr.IPv4AddressKey]remoteIPPrefixDetail)
172185
trie := ipaddr.NewIPv4AddressTrie()
173186

@@ -210,6 +223,21 @@ func refreshRemoteIPs(aws AWSIPRanges, gcp GCPIPRanges, google GoogleIPRanges, a
210223
}
211224
}
212225

226+
for _, prefix := range custom.Prefixes {
227+
ip, err := ipaddr.NewIPAddressString(prefix.IPPrefixStr).ToAddress()
228+
if err != nil {
229+
return nil, nil, fmt.Errorf("invalid IPv4 address %s", prefix.IPPrefixStr)
230+
}
231+
trie.Add(ip.ToIPv4())
232+
d := remoteIPPrefixDetail{
233+
cloud: AWS,
234+
service: prefix.Service,
235+
az: prefix.AvailabilityZone,
236+
}
237+
d.Normalize()
238+
remoteIPRanges[ip.ToIPv4().ToKey()] = d
239+
}
240+
213241
// Parse the prefix, we only care about IPv4 right now.
214242
for _, prefix := range gcp.Prefixes {
215243
if prefix.IPv4PrefixStr == "" {

pkg/labeler/public_ranges_test.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ func TestRefreshRemoteIPs(t *testing.T) {
2929
gcp := GCPIPRanges{}
3030
google := GoogleIPRanges{}
3131
azure := AzureIPRanges{}
32+
custom := CustomIPRanges{}
3233

33-
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure)
34+
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure, custom)
3435
assert.NoError(t, err)
3536
assert.NotNil(t, remoteIPRanges)
3637
assert.NotNil(t, trie)
@@ -62,8 +63,9 @@ func TestRefreshRemoteIPs(t *testing.T) {
6263
gcp := GCPIPRanges{}
6364
google := GoogleIPRanges{}
6465
azure := AzureIPRanges{}
66+
custom := CustomIPRanges{}
6567

66-
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure)
68+
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure, custom)
6769
assert.Error(t, err)
6870
assert.Nil(t, remoteIPRanges)
6971
assert.Nil(t, trie)
@@ -78,8 +80,9 @@ func TestRefreshRemoteIPs(t *testing.T) {
7880
}
7981
google := GoogleIPRanges{}
8082
azure := AzureIPRanges{}
83+
custom := CustomIPRanges{}
8184

82-
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure)
85+
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure, custom)
8386
assert.NoError(t, err)
8487
assert.NotNil(t, remoteIPRanges)
8588
assert.NotNil(t, trie)
@@ -103,8 +106,9 @@ func TestRefreshRemoteIPs(t *testing.T) {
103106
}
104107
google := GoogleIPRanges{}
105108
azure := AzureIPRanges{}
109+
custom := CustomIPRanges{}
106110

107-
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure)
111+
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure, custom)
108112
assert.Error(t, err)
109113
assert.Nil(t, remoteIPRanges)
110114
assert.Nil(t, trie)
@@ -119,8 +123,9 @@ func TestRefreshRemoteIPs(t *testing.T) {
119123
},
120124
}
121125
azure := AzureIPRanges{}
126+
custom := CustomIPRanges{}
122127

123-
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure)
128+
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure, custom)
124129
assert.NoError(t, err)
125130
assert.NotNil(t, remoteIPRanges)
126131
assert.NotNil(t, trie)
@@ -144,8 +149,9 @@ func TestRefreshRemoteIPs(t *testing.T) {
144149
},
145150
}
146151
azure := AzureIPRanges{}
152+
custom := CustomIPRanges{}
147153

148-
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure)
154+
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure, custom)
149155
assert.Error(t, err)
150156
assert.Nil(t, remoteIPRanges)
151157
assert.Nil(t, trie)
@@ -195,8 +201,9 @@ func TestRefreshRemoteIPs(t *testing.T) {
195201
},
196202
},
197203
}
204+
custom := CustomIPRanges{}
198205

199-
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure)
206+
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure, custom)
200207
assert.NoError(t, err)
201208
assert.NotNil(t, remoteIPRanges)
202209
assert.NotNil(t, trie)
@@ -234,8 +241,9 @@ func TestRefreshRemoteIPs(t *testing.T) {
234241
},
235242
},
236243
}
244+
custom := CustomIPRanges{}
237245

238-
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure)
246+
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure, custom)
239247
assert.Error(t, err)
240248
assert.Nil(t, remoteIPRanges)
241249
assert.Nil(t, trie)
@@ -256,8 +264,9 @@ func TestRefreshRemoteIPs(t *testing.T) {
256264
gcp := GCPIPRanges{}
257265
google := GoogleIPRanges{}
258266
azure := AzureIPRanges{}
267+
custom := CustomIPRanges{}
259268

260-
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure)
269+
remoteIPRanges, trie, err := refreshRemoteIPs(aws, gcp, google, azure, custom)
261270
assert.NoError(t, err)
262271
assert.NotNil(t, remoteIPRanges)
263272
assert.NotNil(t, trie)

pkg/labeler/remote.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package labeler
22

33
import (
4+
"encoding/json"
45
"fmt"
6+
"os"
57
"sync"
68
"time"
79

@@ -56,7 +58,12 @@ func NewRemoteLabeler(localRegion string, localCloud Cloud, environment Environm
5658
errorCounter.WithLabelValues([]string{"get_cloud_ranges"}...).Inc()
5759
return nil, fmt.Errorf("error fetching cloud ranges: %v", err)
5860
}
59-
remoteIPPrefixes, remoteIPPrefixesTrie, err := refreshRemoteIPs(aws, gcp, google, azure)
61+
custom, err := getCustomRanges()
62+
if err != nil {
63+
errorCounter.WithLabelValues([]string{"get_custom_ranges"}...).Inc()
64+
return nil, fmt.Errorf("error fetching custom ranges: %v", err)
65+
}
66+
remoteIPPrefixes, remoteIPPrefixesTrie, err := refreshRemoteIPs(aws, gcp, google, azure, custom)
6067
if err != nil {
6168
errorCounter.WithLabelValues([]string{"remote_ips_refresh"}...).Inc()
6269
publicIPRefreshCounter.WithLabelValues([]string{"failed"}...).Inc()
@@ -106,7 +113,14 @@ func NewRemoteLabeler(localRegion string, localCloud Cloud, environment Environm
106113
log.Error().Err(err).Msg("failed to refresh cloud provider IPs")
107114
continue
108115
}
109-
remoteIPPrefixes, remoteIPPrefixesTrie, err := refreshRemoteIPs(aws, gcp, google, azure)
116+
custom, err := getCustomRanges()
117+
if err != nil {
118+
errorCounter.WithLabelValues([]string{"get_custom_ranges"}...).Inc()
119+
publicIPRefreshCounter.WithLabelValues([]string{"failed"}...).Inc()
120+
log.Error().Err(err).Msg("failed to refresh custom provider IPs")
121+
continue
122+
}
123+
remoteIPPrefixes, remoteIPPrefixesTrie, err := refreshRemoteIPs(aws, gcp, google, azure, custom)
110124
if err != nil {
111125
errorCounter.WithLabelValues([]string{"remote_ips_refresh"}...).Inc()
112126
publicIPRefreshCounter.WithLabelValues([]string{"failed"}...).Inc()
@@ -144,6 +158,7 @@ func (l *RemoteLabeler) labelRemote(remoteEndpoint *endpointInfo, FlowData *Flow
144158
FlowData.RemoteRegion = remoteDetail.region
145159
FlowData.RemoteCloudService = remoteDetail.service
146160
FlowData.RemoteCloud = remoteDetail.cloud
161+
FlowData.RemoteAvailabilityZone = remoteDetail.az
147162

148163
if remoteDetail.cloud == l.cloud {
149164
if remoteDetail.region == "" {
@@ -208,3 +223,17 @@ func getCloudRanges() (awsIPRanges AWSIPRanges, gcpIPRanges GCPIPRanges, googleI
208223

209224
return
210225
}
226+
227+
func getCustomRanges() (customIPRanges CustomIPRanges, err error) {
228+
body, err := os.ReadFile("/etc/kubenetmon/custom_ranges.json")
229+
if err != nil {
230+
return customIPRanges, err
231+
}
232+
233+
err = json.Unmarshal(body, &customIPRanges)
234+
if err != nil {
235+
return customIPRanges, err
236+
}
237+
238+
return customIPRanges, err
239+
}

0 commit comments

Comments
 (0)