Skip to content

Commit 20eeccf

Browse files
authored
fix(destination): properly deal with native sidecar port opacity in getProfile (#14791)
(Extracted from #14566) When hitting pods directly at their their IPs, ports in native sidecars that were marked as opaque via the `config.linkerd.io/opaque-ports` annotation, weren't really being marked as opaque. More concretely, the issue layed in the getProfile API, that was forgoing init containers when iterating over containers in this particular case. Endpoint profile translator tests got expanded, testing for opaque ports in both init and regular containers.
1 parent c92c078 commit 20eeccf

File tree

2 files changed

+54
-16
lines changed

2 files changed

+54
-16
lines changed

controller/api/destination/endpoint_profile_translator_test.go

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,49 @@ func TestEndpointProfileTranslator(t *testing.T) {
1818
// logging.SetLevel(logging.TraceLevel)
1919
// defer logging.SetLevel(logging.PanicLevel)
2020

21+
pod := corev1.Pod{
22+
ObjectMeta: metav1.ObjectMeta{
23+
Annotations: map[string]string{
24+
consts.ProxyOpaquePortsAnnotation: "sidecar,http",
25+
},
26+
},
27+
Spec: corev1.PodSpec{
28+
InitContainers: []corev1.Container{
29+
corev1.Container{
30+
Ports: []corev1.ContainerPort{
31+
corev1.ContainerPort{
32+
Name: "sidecar",
33+
ContainerPort: 8081,
34+
},
35+
},
36+
},
37+
},
38+
Containers: []corev1.Container{
39+
corev1.Container{
40+
Ports: []corev1.ContainerPort{
41+
corev1.ContainerPort{
42+
Name: "http",
43+
ContainerPort: 8080,
44+
},
45+
},
46+
},
47+
},
48+
},
49+
}
50+
2151
addr := &watcher.Address{
2252
IP: "10.10.11.11",
2353
Port: 8080,
2454
}
25-
podAddr := &watcher.Address{
55+
podAddr1 := &watcher.Address{
2656
IP: "10.10.11.11",
2757
Port: 8080,
28-
Pod: &corev1.Pod{
29-
ObjectMeta: metav1.ObjectMeta{
30-
Annotations: map[string]string{
31-
consts.ProxyOpaquePortsAnnotation: "8080",
32-
},
33-
},
34-
},
58+
Pod: &pod,
59+
}
60+
podAddr2 := &watcher.Address{
61+
IP: "10.10.11.11",
62+
Port: 8081,
63+
Pod: &pod,
3564
}
3665

3766
t.Run("Sends update", func(t *testing.T) {
@@ -68,13 +97,22 @@ func TestEndpointProfileTranslator(t *testing.T) {
6897
case <-time.After(1 * time.Second):
6998
}
7099

71-
if err := translator.Update(podAddr); err != nil {
100+
if err := translator.Update(podAddr1); err != nil {
72101
t.Fatal("Expected update")
73102
}
74-
select {
75-
case p := <-mockGetProfileServer.profilesReceived:
76-
log.Debugf("Received update: %v", p)
77-
case <-time.After(1 * time.Second):
103+
104+
p1 := <-mockGetProfileServer.profilesReceived
105+
if !p1.GetOpaqueProtocol() {
106+
t.Errorf("Expected port 8080 to be opaque")
107+
}
108+
109+
if err := translator.Update(podAddr2); err != nil {
110+
t.Fatal("Expected update")
111+
}
112+
113+
p2 := <-mockGetProfileServer.profilesReceived
114+
if !p2.GetOpaqueProtocol() {
115+
t.Errorf("Expected port 8081 to be opaque")
78116
}
79117
})
80118

@@ -97,7 +135,7 @@ func TestEndpointProfileTranslator(t *testing.T) {
97135
// queue and we can test the overflow behavior.
98136

99137
for i := 0; i < queueCapacity/2; i++ {
100-
if err := translator.Update(podAddr); err != nil {
138+
if err := translator.Update(podAddr1); err != nil {
101139
t.Fatal("Expected update")
102140
}
103141
select {
@@ -118,7 +156,7 @@ func TestEndpointProfileTranslator(t *testing.T) {
118156

119157
// The queue should be full and the next update should fail.
120158
t.Logf("Queue length=%d capacity=%d", translator.queueLen(), queueCapacity)
121-
if err := translator.Update(podAddr); err == nil {
159+
if err := translator.Update(podAddr1); err == nil {
122160
if !errors.Is(err, http.ErrServerClosed) {
123161
t.Fatalf("Expected update to fail; queue=%d; capacity=%d", translator.queueLen(), queueCapacity)
124162
}

controller/api/destination/watcher/workload_watcher.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ func GetAnnotatedOpaquePorts(pod *corev1.Pod, defaultPorts map[uint32]struct{})
794794
return defaultPorts
795795
}
796796
opaquePorts := make(map[uint32]struct{})
797-
namedPorts := util.GetNamedPorts(pod.Spec.Containers)
797+
namedPorts := util.GetNamedPorts(append(pod.Spec.InitContainers, pod.Spec.Containers...))
798798
if annotation != "" {
799799
for _, pr := range util.ParseContainerOpaquePorts(annotation, namedPorts) {
800800
for _, port := range pr.Ports() {

0 commit comments

Comments
 (0)