Skip to content

Commit a0fe844

Browse files
committed
feat(NSC): honor service-proxy-name label
Abide the service.kubernetes.io/service-proxy-name label as defined by the upstream standard here: https://github.com./kubernetes-sigs/kpng/blob/master/doc/service-proxy.md#ignored-servicesendpoints Resolves the failing e2e test: should implement service.kubernetes.io/service-proxy-name Fixes: #979
1 parent ced5102 commit a0fe844

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

pkg/controllers/proxy/network_services_controller.go

+12
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const (
4545
customDSRRouteTableName = "kube-router-dsr"
4646
externalIPRouteTableID = "79"
4747
externalIPRouteTableName = "external_ip"
48+
kubeRouterProxyName = "kube-router"
4849

4950
// Taken from https://github.com./torvalds/linux/blob/master/include/uapi/linux/ip_vs.h#L21
5051
ipvsPersistentFlagHex = 0x0001
@@ -64,6 +65,7 @@ const (
6465
arpAnnounceUseBestLocalAddress = 2
6566
arpIgnoreReplyOnlyIfTargetIPIsLocal = 1
6667

68+
// kube-router custom labels / annotations
6769
svcDSRAnnotation = "kube-router.io/service.dsr"
6870
svcSchedulerAnnotation = "kube-router.io/service.scheduler"
6971
svcHairpinAnnotation = "kube-router.io/service.hairpin"
@@ -72,6 +74,9 @@ const (
7274
svcSkipLbIpsAnnotation = "kube-router.io/service.skiplbips"
7375
svcSchedFlagsAnnotation = "kube-router.io/service.schedflags"
7476

77+
// kubernetes standard labels / annotations
78+
svcProxyNameLabel = "service.kubernetes.io/service-proxy-name"
79+
7580
// All IPSET names need to be less than 31 characters in order for the Kernel to accept them. Keep in mind that the
7681
// actual formulation for this may be inet6:<setNameBase> depending on ip family, plus when we change ipsets we use
7782
// a swap operation that adds a hyphen to the end, so that means that these base names actually need to be less than
@@ -892,6 +897,13 @@ func (nsc *NetworkServicesController) buildServicesInfo() serviceInfoMap {
892897
continue
893898
}
894899

900+
proxyName, err := getLabelFromMap(svcProxyNameLabel, svc.Labels)
901+
if err == nil && proxyName != kubeRouterProxyName {
902+
klog.V(2).Infof("Skipping service name:%s namespace:%s due to service-proxy-name label not being one "+
903+
"that belongs to kube-router", svc.Name, svc.Namespace)
904+
continue
905+
}
906+
895907
for _, port := range svc.Spec.Ports {
896908
svcInfo := serviceInfo{
897909
clusterIP: net.ParseIP(svc.Spec.ClusterIP),

pkg/controllers/proxy/utils.go

+12
Original file line numberDiff line numberDiff line change
@@ -530,3 +530,15 @@ func runIPCommandsWithArgs(ipArgs []string, additionalArgs ...string) *exec.Cmd
530530
allArgs = append(allArgs, additionalArgs...)
531531
return exec.Command("ip", allArgs...)
532532
}
533+
534+
// getLabelFromMap checks the list of passed labels for the service.kubernetes.io/service-proxy-name
535+
// label and if it exists, returns it otherwise returns an error
536+
func getLabelFromMap(label string, labels map[string]string) (string, error) {
537+
for lbl, val := range labels {
538+
if lbl == label {
539+
return val, nil
540+
}
541+
}
542+
543+
return "", fmt.Errorf("label doesn't exist in map")
544+
}

pkg/controllers/proxy/utils_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,37 @@ func TestNetworkServicesController_lookupServiceByFWMark(t *testing.T) {
131131
assert.Zero(t, foundPort, "port should be zero on error")
132132
})
133133
}
134+
135+
func TestNetworkServicesController_getLabelFromMap(t *testing.T) {
136+
labels := map[string]string{
137+
"service.kubernetes.io": "foo",
138+
"kube-router.io": "bar",
139+
}
140+
copyLabels := func(srcLbls map[string]string) map[string]string {
141+
dstLbls := map[string]string{}
142+
for k, v := range srcLbls {
143+
dstLbls[k] = v
144+
}
145+
return dstLbls
146+
}
147+
t.Run("return blank when passed labels don't contain service-proxy-name label", func(t *testing.T) {
148+
lbl, err := getLabelFromMap(svcProxyNameLabel, labels)
149+
assert.Empty(t, lbl, "should return blank for a list of labels that don't contain a service-proxy-name label")
150+
assert.Error(t, err, "should return an error when the label doesn't exist")
151+
})
152+
153+
t.Run("return blank when empty label map is passed", func(t *testing.T) {
154+
lbls := map[string]string{}
155+
lbl, err := getLabelFromMap(svcProxyNameLabel, lbls)
156+
assert.Empty(t, lbl, "should return blank for a map with no elements")
157+
assert.Error(t, err, "should return an error when the map doesn't contain any elements")
158+
})
159+
160+
t.Run("return value when an labels contains service-proxy-name label", func(t *testing.T) {
161+
lbls := copyLabels(labels)
162+
lbls[svcProxyNameLabel] = "foo"
163+
lbl, err := getLabelFromMap(svcProxyNameLabel, lbls)
164+
assert.Equal(t, "foo", lbl, "should return value when service-proxy-name passed")
165+
assert.Nil(t, err, "error should be nil when the label exists")
166+
})
167+
}

0 commit comments

Comments
 (0)