Skip to content

Commit 0490f25

Browse files
AlinsRanronething
authored andcommitted
fix(ingress): port.name matching failure for ExternalName Services (#2604)
1 parent 75df484 commit 0490f25

File tree

3 files changed

+69
-30
lines changed

3 files changed

+69
-30
lines changed

internal/adc/translator/ingress.go

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
discoveryv1 "k8s.io/api/discovery/v1"
2626
networkingv1 "k8s.io/api/networking/v1"
2727
"k8s.io/apimachinery/pkg/types"
28+
"k8s.io/apimachinery/pkg/util/intstr"
2829
"k8s.io/utils/ptr"
2930

3031
adctypes "github.com/apache/apisix-ingress-controller/api/adc"
@@ -172,12 +173,11 @@ func (t *Translator) resolveIngressUpstream(
172173
t.AttachBackendTrafficPolicyToUpstream(backendRef, tctx.BackendTrafficPolicies, upstream)
173174
// determine service port/port name
174175
var protocol string
175-
var servicePort int32 = 0
176-
var servicePortName string
176+
var port intstr.IntOrString
177177
if backendService.Port.Number != 0 {
178-
servicePort = backendService.Port.Number
178+
port = intstr.FromInt32(backendService.Port.Number)
179179
} else if backendService.Port.Name != "" {
180-
servicePortName = backendService.Port.Name
180+
port = intstr.FromString(backendService.Port.Name)
181181
}
182182

183183
getService := tctx.Services[types.NamespacedName{
@@ -187,43 +187,28 @@ func (t *Translator) resolveIngressUpstream(
187187
if getService == nil {
188188
return protocol
189189
}
190-
190+
getServicePort, _ := findMatchingServicePort(getService, port)
191+
if getServicePort != nil && getServicePort.AppProtocol != nil {
192+
protocol = *getServicePort.AppProtocol
193+
if upstream.Scheme == "" {
194+
upstream.Scheme = appProtocolToUpstreamScheme(*getServicePort.AppProtocol)
195+
}
196+
}
191197
if getService.Spec.Type == corev1.ServiceTypeExternalName {
192-
defaultServicePort := 80
193-
if servicePort > 0 {
194-
defaultServicePort = int(servicePort)
198+
servicePort := 80
199+
if getServicePort != nil {
200+
servicePort = int(getServicePort.Port)
195201
}
196202
upstream.Nodes = adctypes.UpstreamNodes{
197203
{
198204
Host: getService.Spec.ExternalName,
199-
Port: defaultServicePort,
205+
Port: servicePort,
200206
Weight: 1,
201207
},
202208
}
203209
return protocol
204210
}
205211

206-
// find matching service port object
207-
var getServicePort *corev1.ServicePort
208-
for _, port := range getService.Spec.Ports {
209-
p := port
210-
if servicePort > 0 && p.Port == servicePort {
211-
getServicePort = &p
212-
break
213-
}
214-
if servicePortName != "" && p.Name == servicePortName {
215-
getServicePort = &p
216-
break
217-
}
218-
}
219-
220-
if getServicePort != nil && getServicePort.AppProtocol != nil {
221-
protocol = *getServicePort.AppProtocol
222-
if upstream.Scheme == "" {
223-
upstream.Scheme = appProtocolToUpstreamScheme(*getServicePort.AppProtocol)
224-
}
225-
}
226-
227212
endpointSlices := tctx.EndpointSlices[types.NamespacedName{
228213
Namespace: obj.Namespace,
229214
Name: backendService.Name,

test/e2e/ingress/ingress.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,36 @@ spec:
227227
name: httpbin-external-domain
228228
port:
229229
number: 80
230+
`
231+
var ingressWithExternalNamePortName = `
232+
apiVersion: v1
233+
kind: Service
234+
metadata:
235+
name: httpbin-external-domain
236+
spec:
237+
type: ExternalName
238+
externalName: httpbin-service-e2e-test
239+
ports:
240+
- name: http
241+
port: 8080
242+
protocol: TCP
243+
---
244+
apiVersion: networking.k8s.io/v1
245+
kind: Ingress
246+
metadata:
247+
name: ingress-external-name-port-name
248+
spec:
249+
rules:
250+
- host: httpbin.external
251+
http:
252+
paths:
253+
- path: /
254+
pathType: Prefix
255+
backend:
256+
service:
257+
name: httpbin-external-domain
258+
port:
259+
name: http
230260
`
231261
BeforeEach(func() {
232262
By("create GatewayProxy")
@@ -294,6 +324,26 @@ spec:
294324
})
295325
})
296326

327+
It("Mathch Service Port by Name", func() {
328+
By("create Ingress")
329+
err := s.CreateResourceFromString(ingressWithExternalNamePortName)
330+
Expect(err).NotTo(HaveOccurred(), "creating Ingress without IngressClass")
331+
332+
By("checking the external service response")
333+
s.RequestAssert(&scaffold.RequestAssert{
334+
Method: "GET",
335+
Path: "/get",
336+
Host: "httpbin.external",
337+
Check: scaffold.WithExpectedStatus(http.StatusOK),
338+
})
339+
340+
upstreams, err := s.DefaultDataplaneResource().Upstream().List(context.Background())
341+
Expect(err).NotTo(HaveOccurred(), "listing Upstream")
342+
Expect(upstreams).To(HaveLen(1), "the number of Upstream")
343+
Expect(upstreams[0].Nodes).To(HaveLen(1), "the number of Upstream nodes")
344+
Expect(upstreams[0].Nodes[0].Port).To(Equal(8080), "the port of Upstream node")
345+
})
346+
297347
It("Delete Ingress during restart", func() {
298348
By("create Ingress with ExternalName")
299349
ingressName := s.Namespace() + "-external"

test/e2e/scaffold/httpbin.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ spec:
8989
port: 80
9090
protocol: TCP
9191
targetPort: 80
92+
- name: http-v2
93+
port: 8080
94+
protocol: TCP
95+
targetPort: 80
9296
type: ClusterIP
9397
`
9498
)

0 commit comments

Comments
 (0)