@@ -24,7 +24,7 @@ import (
2424 "strconv"
2525
2626 "github.com/pkg/errors"
27- v1 "k8s.io/api/core/v1"
27+ corev1 "k8s.io/api/core/v1"
2828 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2929 "k8s.io/apimachinery/pkg/types"
3030 "k8s.io/apimachinery/pkg/util/intstr"
@@ -70,10 +70,10 @@ func (t *Translator) translateHTTPRule(tctx *provider.TranslateContext, ar *apiv
7070 return nil , err
7171 }
7272
73+ var enableWebsocket * bool
7374 service := t .buildService (ar , rule , ruleIndex )
74- t .buildRoute (ar , service , rule , plugins , timeout , vars )
75- t .buildUpstream (tctx , service , ar , rule )
76-
75+ t .buildUpstream (tctx , service , ar , rule , & enableWebsocket )
76+ t .buildRoute (ar , service , rule , plugins , timeout , vars , & enableWebsocket )
7777 return service , nil
7878}
7979
@@ -139,7 +139,7 @@ func (t *Translator) loadRoutePlugins(tctx *provider.TranslateContext, ar *apiv2
139139 }
140140}
141141
142- func (t * Translator ) buildPluginConfig (plugin apiv2.ApisixRoutePlugin , namespace string , secrets map [types.NamespacedName ]* v1 .Secret ) map [string ]any {
142+ func (t * Translator ) buildPluginConfig (plugin apiv2.ApisixRoutePlugin , namespace string , secrets map [types.NamespacedName ]* corev1 .Secret ) map [string ]any {
143143 config := make (map [string ]any )
144144 if len (plugin .Config .Raw ) > 0 {
145145 if err := json .Unmarshal (plugin .Config .Raw , & config ); err != nil {
@@ -179,13 +179,16 @@ func (t *Translator) addAuthenticationPlugins(rule apiv2.ApisixRouteHTTP, plugin
179179 }
180180}
181181
182- func (t * Translator ) buildRoute (ar * apiv2.ApisixRoute , service * adc.Service , rule apiv2.ApisixRouteHTTP , plugins adc.Plugins , timeout * adc.Timeout , vars adc.Vars ) {
182+ func (t * Translator ) buildRoute (ar * apiv2.ApisixRoute , service * adc.Service , rule apiv2.ApisixRouteHTTP , plugins adc.Plugins , timeout * adc.Timeout , vars adc.Vars , enableWebsocket * * bool ) {
183183 route := adc .NewDefaultRoute ()
184184 route .Name = adc .ComposeRouteName (ar .Namespace , ar .Name , rule .Name )
185185 route .ID = id .GenID (route .Name )
186186 route .Desc = "Created by apisix-ingress-controller, DO NOT modify it manually"
187187 route .Labels = label .GenLabel (ar )
188- route .EnableWebsocket = ptr .To (rule .Websocket )
188+ route .EnableWebsocket = rule .Websocket
189+ if route .EnableWebsocket == nil && * enableWebsocket != nil {
190+ route .EnableWebsocket = * enableWebsocket
191+ }
189192 route .FilterFunc = rule .Match .FilterFunc
190193 route .Hosts = rule .Match .Hosts
191194 route .Methods = rule .Match .Methods
@@ -202,7 +205,7 @@ func (t *Translator) buildRoute(ar *apiv2.ApisixRoute, service *adc.Service, rul
202205 service .Routes = []* adc.Route {route }
203206}
204207
205- func (t * Translator ) buildUpstream (tctx * provider.TranslateContext , service * adc.Service , ar * apiv2.ApisixRoute , rule apiv2.ApisixRouteHTTP ) {
208+ func (t * Translator ) buildUpstream (tctx * provider.TranslateContext , service * adc.Service , ar * apiv2.ApisixRoute , rule apiv2.ApisixRouteHTTP , enableWebsocket * * bool ) {
206209 var (
207210 upstreams = make ([]* adc.Upstream , 0 )
208211 weightedUpstreams = make ([]adc.TrafficSplitConfigRuleWeightedUpstream , 0 )
@@ -211,7 +214,7 @@ func (t *Translator) buildUpstream(tctx *provider.TranslateContext, service *adc
211214 for _ , backend := range rule .Backends {
212215 // try to get the apisixupstream with the same name as the backend service to be upstream config.
213216 // err is ignored because it does not care about the externalNodes of the apisixupstream.
214- upstream , err := t .translateApisixRouteHTTPBackend (tctx , ar , backend )
217+ upstream , err := t .translateApisixRouteHTTPBackend (tctx , ar , backend , enableWebsocket )
215218 if err != nil {
216219 t .Log .Error (err , "failed to translate ApisixRoute backend" , "backend" , backend )
217220 continue
@@ -310,7 +313,7 @@ func (t *Translator) buildService(ar *apiv2.ApisixRoute, rule apiv2.ApisixRouteH
310313 return service
311314}
312315
313- func getPortFromService (svc * v1 .Service , backendSvcPort intstr.IntOrString ) (int32 , error ) {
316+ func getPortFromService (svc * corev1 .Service , backendSvcPort intstr.IntOrString ) (int32 , error ) {
314317 var port int32
315318 if backendSvcPort .Type == intstr .Int {
316319 port = int32 (backendSvcPort .IntValue ())
@@ -330,7 +333,31 @@ func getPortFromService(svc *v1.Service, backendSvcPort intstr.IntOrString) (int
330333 return port , nil
331334}
332335
333- func (t * Translator ) translateApisixRouteHTTPBackend (tctx * provider.TranslateContext , ar * apiv2.ApisixRoute , backend apiv2.ApisixRouteHTTPBackend ) (* adc.Upstream , error ) {
336+ func findMatchingServicePort (svc * corev1.Service , backendSvcPort intstr.IntOrString ) (* corev1.ServicePort , error ) {
337+ var servicePort * corev1.ServicePort
338+ var portNumber int32 = - 1
339+ var servicePortName string
340+ switch backendSvcPort .Type {
341+ case intstr .Int :
342+ portNumber = backendSvcPort .IntVal
343+ case intstr .String :
344+ servicePortName = backendSvcPort .StrVal
345+ }
346+ for _ , svcPort := range svc .Spec .Ports {
347+ p := svcPort
348+ if p .Port == portNumber || (p .Name != "" && p .Name == servicePortName ) {
349+ servicePort = & p
350+ break
351+ }
352+ }
353+ if servicePort == nil {
354+ return nil , errors .Errorf ("service port %s not found in service %s" , backendSvcPort .String (), svc .Name )
355+ }
356+
357+ return servicePort , nil
358+ }
359+
360+ func (t * Translator ) translateApisixRouteHTTPBackend (tctx * provider.TranslateContext , ar * apiv2.ApisixRoute , backend apiv2.ApisixRouteHTTPBackend , enableWebsocket * * bool ) (* adc.Upstream , error ) {
334361 auNN := types.NamespacedName {
335362 Namespace : ar .Namespace ,
336363 Name : backend .ServiceName ,
@@ -352,50 +379,57 @@ func (t *Translator) translateApisixRouteHTTPBackend(tctx *provider.TranslateCon
352379 upstream = u
353380 }
354381 var (
355- err error
356- nodes adc.UpstreamNodes
382+ err error
383+ nodes adc.UpstreamNodes
384+ protocol string
357385 )
358386 if backend .ResolveGranularity == apiv2 .ResolveGranularityService {
359- nodes , err = t .translateApisixRouteBackendResolveGranularityService (tctx , auNN , backend )
387+ nodes , protocol , err = t .translateApisixRouteBackendResolveGranularityService (tctx , auNN , backend )
360388 } else {
361- nodes , err = t .translateApisixRouteBackendResolveGranularityEndpoint (tctx , auNN , backend )
389+ nodes , protocol , err = t .translateApisixRouteBackendResolveGranularityEndpoint (tctx , auNN , backend )
362390 }
363391 if err != nil {
364392 return nil , err
365393 }
366394 upstream .Nodes = nodes
395+ if upstream .Scheme == "" {
396+ upstream .Scheme = appProtocolToUpstreamScheme (protocol )
397+ }
398+ if protocol == internaltypes .AppProtocolWS || protocol == internaltypes .AppProtocolWSS {
399+ * enableWebsocket = ptr .To (true )
400+ }
367401 if backend .Weight != nil {
368402 upstream .Labels ["meta_weight" ] = strconv .FormatInt (int64 (* backend .Weight ), 10 )
369403 }
370404 return upstream , nil
371405}
372406
373- func (t * Translator ) translateApisixRouteBackendResolveGranularityService (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteHTTPBackend ) (adc.UpstreamNodes , error ) {
407+ func (t * Translator ) translateApisixRouteBackendResolveGranularityService (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteHTTPBackend ) (adc.UpstreamNodes , string , error ) {
374408 serviceNN := types.NamespacedName {
375409 Namespace : arNN .Namespace ,
376410 Name : backend .ServiceName ,
377411 }
378412 svc , ok := tctx .Services [serviceNN ]
379413 if ! ok {
380- return nil , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
414+ return nil , "" , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
381415 }
382416 if svc .Spec .ClusterIP == "" {
383- return nil , errors .Errorf ("conflict headless service and backend resolve granularity, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
417+ return nil , "" , errors .Errorf ("conflict headless service and backend resolve granularity, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
384418 }
385- port , err := getPortFromService (svc , backend .ServicePort )
419+ port , err := findMatchingServicePort (svc , backend .ServicePort )
386420 if err != nil {
387- return nil , err
421+ return nil , "" , err
388422 }
389423 return adc.UpstreamNodes {
390424 {
391425 Host : svc .Spec .ClusterIP ,
392- Port : int (port ),
426+ Port : int (port . Port ),
393427 Weight : * cmp .Or (backend .Weight , ptr .To (apiv2 .DefaultWeight )),
394428 },
395- }, nil
429+ }, ptr . Deref ( port . AppProtocol , "" ), nil
396430}
397431
398- func (t * Translator ) translateApisixRouteStreamBackendResolveGranularity (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteStreamBackend ) (adc.UpstreamNodes , error ) {
432+ func (t * Translator ) translateApisixRouteStreamBackendResolveGranularity (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteStreamBackend ) (adc.UpstreamNodes , string , error ) {
399433 tsBackend := apiv2.ApisixRouteHTTPBackend {
400434 ServiceName : backend .ServiceName ,
401435 ServicePort : backend .ServicePort ,
@@ -409,18 +443,18 @@ func (t *Translator) translateApisixRouteStreamBackendResolveGranularity(tctx *p
409443 }
410444}
411445
412- func (t * Translator ) translateApisixRouteBackendResolveGranularityEndpoint (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteHTTPBackend ) (adc.UpstreamNodes , error ) {
446+ func (t * Translator ) translateApisixRouteBackendResolveGranularityEndpoint (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteHTTPBackend ) (adc.UpstreamNodes , string , error ) {
413447 serviceNN := types.NamespacedName {
414448 Namespace : arNN .Namespace ,
415449 Name : backend .ServiceName ,
416450 }
417451 svc , ok := tctx .Services [serviceNN ]
418452 if ! ok {
419- return nil , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
453+ return nil , "" , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
420454 }
421455 port , err := getPortFromService (svc , backend .ServicePort )
422456 if err != nil {
423- return nil , err
457+ return nil , "" , err
424458 }
425459 weight := int32 (* cmp .Or (backend .Weight , ptr .To (apiv2 .DefaultWeight )))
426460 backendRef := gatewayv1.BackendRef {
@@ -482,7 +516,7 @@ func (t *Translator) translateApisixRouteStreamBackend(tctx *provider.TranslateC
482516 }
483517 upstream = u
484518 }
485- nodes , err := t .translateApisixRouteStreamBackendResolveGranularity (tctx , utils .NamespacedName (ar ), backend )
519+ nodes , _ , err := t .translateApisixRouteStreamBackendResolveGranularity (tctx , utils .NamespacedName (ar ), backend )
486520 if err != nil {
487521 return nil , err
488522 }
0 commit comments