@@ -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,9 +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 , ruleIndex )
75+ t .buildRoute (ar , service , rule , plugins , timeout , vars , & enableWebsocket )
76+ t .buildUpstream (tctx , service , ar , rule , ruleIndex , & enableWebsocket )
7677
7778 return service , nil
7879}
@@ -139,7 +140,7 @@ func (t *Translator) loadRoutePlugins(tctx *provider.TranslateContext, ar *apiv2
139140 }
140141}
141142
142- func (t * Translator ) buildPluginConfig (plugin apiv2.ApisixRoutePlugin , namespace string , secrets map [types.NamespacedName ]* v1 .Secret ) map [string ]any {
143+ func (t * Translator ) buildPluginConfig (plugin apiv2.ApisixRoutePlugin , namespace string , secrets map [types.NamespacedName ]* corev1 .Secret ) map [string ]any {
143144 config := make (map [string ]any )
144145 if len (plugin .Config .Raw ) > 0 {
145146 if err := json .Unmarshal (plugin .Config .Raw , & config ); err != nil {
@@ -179,13 +180,16 @@ func (t *Translator) addAuthenticationPlugins(rule apiv2.ApisixRouteHTTP, plugin
179180 }
180181}
181182
182- func (t * Translator ) buildRoute (ar * apiv2.ApisixRoute , service * adc.Service , rule apiv2.ApisixRouteHTTP , plugins adc.Plugins , timeout * adc.Timeout , vars adc.Vars ) {
183+ func (t * Translator ) buildRoute (ar * apiv2.ApisixRoute , service * adc.Service , rule apiv2.ApisixRouteHTTP , plugins adc.Plugins , timeout * adc.Timeout , vars adc.Vars , enableWebsocket * * bool ) {
183184 route := adc .NewDefaultRoute ()
184185 route .Name = adc .ComposeRouteName (ar .Namespace , ar .Name , rule .Name )
185186 route .ID = id .GenID (route .Name )
186187 route .Desc = "Created by apisix-ingress-controller, DO NOT modify it manually"
187188 route .Labels = label .GenLabel (ar )
188- route .EnableWebsocket = ptr .To (rule .Websocket )
189+ route .EnableWebsocket = rule .Websocket
190+ if route .EnableWebsocket == nil && * enableWebsocket != nil {
191+ route .EnableWebsocket = * enableWebsocket
192+ }
189193 route .FilterFunc = rule .Match .FilterFunc
190194 route .Hosts = rule .Match .Hosts
191195 route .Methods = rule .Match .Methods
@@ -202,7 +206,7 @@ func (t *Translator) buildRoute(ar *apiv2.ApisixRoute, service *adc.Service, rul
202206 service .Routes = []* adc.Route {route }
203207}
204208
205- func (t * Translator ) buildUpstream (tctx * provider.TranslateContext , service * adc.Service , ar * apiv2.ApisixRoute , rule apiv2.ApisixRouteHTTP , ruleIndex int ) {
209+ func (t * Translator ) buildUpstream (tctx * provider.TranslateContext , service * adc.Service , ar * apiv2.ApisixRoute , rule apiv2.ApisixRouteHTTP , ruleIndex int , enableWebsocket * * bool ) {
206210 var (
207211 upstreams = make ([]* adc.Upstream , 0 )
208212 weightedUpstreams = make ([]adc.TrafficSplitConfigRuleWeightedUpstream , 0 )
@@ -211,7 +215,7 @@ func (t *Translator) buildUpstream(tctx *provider.TranslateContext, service *adc
211215 for backendIndex , backend := range rule .Backends {
212216 // try to get the apisixupstream with the same name as the backend service to be upstream config.
213217 // err is ignored because it does not care about the externalNodes of the apisixupstream.
214- upstream , err := t .translateApisixRouteHTTPBackend (tctx , ar , backend )
218+ upstream , err := t .translateApisixRouteHTTPBackend (tctx , ar , backend , enableWebsocket )
215219 if err != nil {
216220 t .Log .Error (err , "failed to translate ApisixRoute backend" , "backend" , backend )
217221 continue
@@ -312,7 +316,7 @@ func (t *Translator) buildService(ar *apiv2.ApisixRoute, rule apiv2.ApisixRouteH
312316 return service
313317}
314318
315- func getPortFromService (svc * v1 .Service , backendSvcPort intstr.IntOrString ) (int32 , error ) {
319+ func getPortFromService (svc * corev1 .Service , backendSvcPort intstr.IntOrString ) (int32 , error ) {
316320 var port int32
317321 if backendSvcPort .Type == intstr .Int {
318322 port = int32 (backendSvcPort .IntValue ())
@@ -332,7 +336,31 @@ func getPortFromService(svc *v1.Service, backendSvcPort intstr.IntOrString) (int
332336 return port , nil
333337}
334338
335- func (t * Translator ) translateApisixRouteHTTPBackend (tctx * provider.TranslateContext , ar * apiv2.ApisixRoute , backend apiv2.ApisixRouteHTTPBackend ) (* adc.Upstream , error ) {
339+ func findMatchingServicePort (svc * corev1.Service , backendSvcPort intstr.IntOrString ) (* corev1.ServicePort , error ) {
340+ var servicePort * corev1.ServicePort
341+ var portNumber int32 = - 1
342+ var servicePortName string
343+ switch backendSvcPort .Type {
344+ case intstr .Int :
345+ portNumber = backendSvcPort .IntVal
346+ case intstr .String :
347+ servicePortName = backendSvcPort .StrVal
348+ }
349+ for _ , svcPort := range svc .Spec .Ports {
350+ p := svcPort
351+ if p .Port == portNumber || (p .Name != "" && p .Name == servicePortName ) {
352+ servicePort = & p
353+ break
354+ }
355+ }
356+ if servicePort == nil {
357+ return nil , errors .Errorf ("service port %s not found in service %s" , backendSvcPort .String (), svc .Name )
358+ }
359+
360+ return servicePort , nil
361+ }
362+
363+ func (t * Translator ) translateApisixRouteHTTPBackend (tctx * provider.TranslateContext , ar * apiv2.ApisixRoute , backend apiv2.ApisixRouteHTTPBackend , enableWebsocket * * bool ) (* adc.Upstream , error ) {
336364 auNN := types.NamespacedName {
337365 Namespace : ar .Namespace ,
338366 Name : backend .ServiceName ,
@@ -354,50 +382,57 @@ func (t *Translator) translateApisixRouteHTTPBackend(tctx *provider.TranslateCon
354382 upstream = u
355383 }
356384 var (
357- err error
358- nodes adc.UpstreamNodes
385+ err error
386+ nodes adc.UpstreamNodes
387+ protocol string
359388 )
360389 if backend .ResolveGranularity == apiv2 .ResolveGranularityService {
361- nodes , err = t .translateApisixRouteBackendResolveGranularityService (tctx , auNN , backend )
390+ nodes , protocol , err = t .translateApisixRouteBackendResolveGranularityService (tctx , auNN , backend )
362391 } else {
363- nodes , err = t .translateApisixRouteBackendResolveGranularityEndpoint (tctx , auNN , backend )
392+ nodes , protocol , err = t .translateApisixRouteBackendResolveGranularityEndpoint (tctx , auNN , backend )
364393 }
365394 if err != nil {
366395 return nil , err
367396 }
368397 upstream .Nodes = nodes
398+ if upstream .Scheme == "" {
399+ upstream .Scheme = appProtocolToUpstreamScheme (protocol )
400+ }
401+ if protocol == internaltypes .AppProtocolWS || protocol == internaltypes .AppProtocolWSS {
402+ * enableWebsocket = ptr .To (true )
403+ }
369404 if backend .Weight != nil {
370405 upstream .Labels ["meta_weight" ] = strconv .FormatInt (int64 (* backend .Weight ), 10 )
371406 }
372407 return upstream , nil
373408}
374409
375- func (t * Translator ) translateApisixRouteBackendResolveGranularityService (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteHTTPBackend ) (adc.UpstreamNodes , error ) {
410+ func (t * Translator ) translateApisixRouteBackendResolveGranularityService (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteHTTPBackend ) (adc.UpstreamNodes , string , error ) {
376411 serviceNN := types.NamespacedName {
377412 Namespace : arNN .Namespace ,
378413 Name : backend .ServiceName ,
379414 }
380415 svc , ok := tctx .Services [serviceNN ]
381416 if ! ok {
382- return nil , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
417+ return nil , "" , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
383418 }
384419 if svc .Spec .ClusterIP == "" {
385- return nil , errors .Errorf ("conflict headless service and backend resolve granularity, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
420+ return nil , "" , errors .Errorf ("conflict headless service and backend resolve granularity, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
386421 }
387- port , err := getPortFromService (svc , backend .ServicePort )
422+ port , err := findMatchingServicePort (svc , backend .ServicePort )
388423 if err != nil {
389- return nil , err
424+ return nil , "" , err
390425 }
391426 return adc.UpstreamNodes {
392427 {
393428 Host : svc .Spec .ClusterIP ,
394- Port : int (port ),
429+ Port : int (port . Port ),
395430 Weight : * cmp .Or (backend .Weight , ptr .To (apiv2 .DefaultWeight )),
396431 },
397- }, nil
432+ }, ptr . Deref ( port . AppProtocol , "" ), nil
398433}
399434
400- func (t * Translator ) translateApisixRouteStreamBackendResolveGranularity (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteStreamBackend ) (adc.UpstreamNodes , error ) {
435+ func (t * Translator ) translateApisixRouteStreamBackendResolveGranularity (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteStreamBackend ) (adc.UpstreamNodes , string , error ) {
401436 tsBackend := apiv2.ApisixRouteHTTPBackend {
402437 ServiceName : backend .ServiceName ,
403438 ServicePort : backend .ServicePort ,
@@ -411,18 +446,18 @@ func (t *Translator) translateApisixRouteStreamBackendResolveGranularity(tctx *p
411446 }
412447}
413448
414- func (t * Translator ) translateApisixRouteBackendResolveGranularityEndpoint (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteHTTPBackend ) (adc.UpstreamNodes , error ) {
449+ func (t * Translator ) translateApisixRouteBackendResolveGranularityEndpoint (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteHTTPBackend ) (adc.UpstreamNodes , string , error ) {
415450 serviceNN := types.NamespacedName {
416451 Namespace : arNN .Namespace ,
417452 Name : backend .ServiceName ,
418453 }
419454 svc , ok := tctx .Services [serviceNN ]
420455 if ! ok {
421- return nil , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
456+ return nil , "" , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
422457 }
423458 port , err := getPortFromService (svc , backend .ServicePort )
424459 if err != nil {
425- return nil , err
460+ return nil , "" , err
426461 }
427462 weight := int32 (* cmp .Or (backend .Weight , ptr .To (apiv2 .DefaultWeight )))
428463 backendRef := gatewayv1.BackendRef {
@@ -484,7 +519,7 @@ func (t *Translator) translateApisixRouteStreamBackend(tctx *provider.TranslateC
484519 }
485520 upstream = u
486521 }
487- nodes , err := t .translateApisixRouteStreamBackendResolveGranularity (tctx , utils .NamespacedName (ar ), backend )
522+ nodes , _ , err := t .translateApisixRouteStreamBackendResolveGranularity (tctx , utils .NamespacedName (ar ), backend )
488523 if err != nil {
489524 return nil , err
490525 }
0 commit comments