Skip to content

Commit b02e842

Browse files
authored
fix(backport): preserve HTTPRoute upstream scheme from backend ref (#395)
1 parent 23ee25f commit b02e842

2 files changed

Lines changed: 153 additions & 1 deletion

File tree

internal/adc/translator/httproute.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,9 @@ func (t *Translator) TranslateHTTPRoute(tctx *provider.TranslateContext, httpRou
572572

573573
t.AttachBackendTrafficPolicyToUpstream(backend.BackendRef, tctx.BackendTrafficPolicies, upstream)
574574
upstream.Nodes = upNodes
575-
upstream.Scheme = appProtocolToUpstreamScheme(protocol)
575+
if upstream.Scheme == "" {
576+
upstream.Scheme = appProtocolToUpstreamScheme(protocol)
577+
}
576578
var (
577579
kind string
578580
port int32
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package translator
19+
20+
import (
21+
"context"
22+
"testing"
23+
24+
"github.com/go-logr/logr"
25+
"github.com/stretchr/testify/assert"
26+
"github.com/stretchr/testify/require"
27+
corev1 "k8s.io/api/core/v1"
28+
discoveryv1 "k8s.io/api/discovery/v1"
29+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30+
"k8s.io/apimachinery/pkg/types"
31+
"k8s.io/utils/ptr"
32+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
33+
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
34+
35+
"github.com/apache/apisix-ingress-controller/api/v1alpha1"
36+
apiv2 "github.com/apache/apisix-ingress-controller/api/v2"
37+
"github.com/apache/apisix-ingress-controller/internal/provider"
38+
internaltypes "github.com/apache/apisix-ingress-controller/internal/types"
39+
)
40+
41+
func TestTranslateHTTPRouteUpstreamScheme(t *testing.T) {
42+
tests := []struct {
43+
name string
44+
appProtocol string
45+
policyScheme string
46+
wantScheme string
47+
}{
48+
{
49+
name: "preserves backend traffic policy scheme",
50+
appProtocol: internaltypes.AppProtocolHTTP,
51+
policyScheme: apiv2.SchemeHTTPS,
52+
wantScheme: apiv2.SchemeHTTPS,
53+
},
54+
{
55+
name: "falls back to app protocol when scheme is unset",
56+
appProtocol: internaltypes.AppProtocolWSS,
57+
wantScheme: apiv2.SchemeHTTPS,
58+
},
59+
}
60+
61+
for _, tt := range tests {
62+
t.Run(tt.name, func(t *testing.T) {
63+
translator := NewTranslator(logr.Discard())
64+
tctx := provider.NewDefaultTranslateContext(context.Background())
65+
66+
const (
67+
namespace = "default"
68+
serviceName = "backend"
69+
portName = "web"
70+
portNumber = int32(8443)
71+
)
72+
73+
serviceKey := types.NamespacedName{Namespace: namespace, Name: serviceName}
74+
tctx.Services[serviceKey] = &corev1.Service{
75+
ObjectMeta: metav1.ObjectMeta{
76+
Name: serviceName,
77+
Namespace: namespace,
78+
},
79+
Spec: corev1.ServiceSpec{
80+
Ports: []corev1.ServicePort{{
81+
Name: portName,
82+
Port: portNumber,
83+
AppProtocol: ptr.To(tt.appProtocol),
84+
}},
85+
},
86+
}
87+
tctx.EndpointSlices[serviceKey] = []discoveryv1.EndpointSlice{{
88+
ObjectMeta: metav1.ObjectMeta{
89+
Name: "backend-1",
90+
Namespace: namespace,
91+
},
92+
Ports: []discoveryv1.EndpointPort{{
93+
Name: ptr.To(portName),
94+
Port: ptr.To(portNumber),
95+
}},
96+
Endpoints: []discoveryv1.Endpoint{{
97+
Addresses: []string{"10.0.0.1"},
98+
Conditions: discoveryv1.EndpointConditions{
99+
Ready: ptr.To(true),
100+
},
101+
}},
102+
}}
103+
104+
if tt.policyScheme != "" {
105+
tctx.BackendTrafficPolicies[serviceKey] = &v1alpha1.BackendTrafficPolicy{
106+
ObjectMeta: metav1.ObjectMeta{
107+
Name: "backend-policy",
108+
Namespace: namespace,
109+
},
110+
Spec: v1alpha1.BackendTrafficPolicySpec{
111+
TargetRefs: []v1alpha1.BackendPolicyTargetReferenceWithSectionName{{
112+
LocalPolicyTargetReference: gatewayv1alpha2.LocalPolicyTargetReference{
113+
Name: gatewayv1alpha2.ObjectName(serviceName),
114+
Kind: gatewayv1alpha2.Kind(internaltypes.KindService),
115+
},
116+
}},
117+
Scheme: tt.policyScheme,
118+
},
119+
}
120+
}
121+
122+
route := &gatewayv1.HTTPRoute{
123+
ObjectMeta: metav1.ObjectMeta{
124+
Name: "demo",
125+
Namespace: namespace,
126+
},
127+
Spec: gatewayv1.HTTPRouteSpec{
128+
Rules: []gatewayv1.HTTPRouteRule{{
129+
BackendRefs: []gatewayv1.HTTPBackendRef{{
130+
BackendRef: gatewayv1.BackendRef{
131+
BackendObjectReference: gatewayv1.BackendObjectReference{
132+
Name: gatewayv1.ObjectName(serviceName),
133+
Port: ptr.To(gatewayv1.PortNumber(portNumber)),
134+
},
135+
},
136+
}},
137+
}},
138+
},
139+
}
140+
141+
result, err := translator.TranslateHTTPRoute(tctx, route)
142+
require.NoError(t, err)
143+
require.Len(t, result.Services, 1)
144+
require.NotNil(t, result.Services[0].Upstream)
145+
146+
assert.Equal(t, tt.wantScheme, result.Services[0].Upstream.Scheme)
147+
assert.Equal(t, "10.0.0.1", result.Services[0].Upstream.Nodes[0].Host)
148+
})
149+
}
150+
}

0 commit comments

Comments
 (0)