@@ -25,8 +25,12 @@ import (
2525
2626 "github.com/api7/gopkg/pkg/log"
2727 "github.com/pkg/errors"
28+ << << << < HEAD
2829 "go.uber.org/zap"
2930 v1 "k8s.io/api/core/v1"
31+ == == == =
32+ corev1 "k8s.io/api/core/v1"
33+ >> >> >> > f28b3429 (feat : support resolve svc .ports [].appProtocol (#2601 ))
3034 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3135 "k8s.io/apimachinery/pkg/types"
3236 "k8s.io/apimachinery/pkg/util/intstr"
@@ -72,10 +76,16 @@ func (t *Translator) translateHTTPRule(tctx *provider.TranslateContext, ar *apiv
7276 return nil , err
7377 }
7478
79+ var enableWebsocket * bool
7580 service := t .buildService (ar , rule , ruleIndex )
81+ << << << < HEAD
7682 t .buildRoute (ar , service , rule , plugins , timeout , vars )
7783 t .buildUpstream (tctx , service , ar , rule , ruleIndex )
7884
85+ == == == =
86+ t .buildUpstream (tctx , service , ar , rule , & enableWebsocket )
87+ t .buildRoute (ar , service , rule , plugins , timeout , vars , & enableWebsocket )
88+ >> >> >> > f28b3429 (feat : support resolve svc.ports [].appProtocol (#2601 ))
7989 return service , nil
8090}
8191
@@ -141,7 +151,7 @@ func (t *Translator) loadRoutePlugins(tctx *provider.TranslateContext, ar *apiv2
141151 }
142152}
143153
144- func (t * Translator ) buildPluginConfig (plugin apiv2.ApisixRoutePlugin , namespace string , secrets map [types.NamespacedName ]* v1 .Secret ) map [string ]any {
154+ func (t * Translator ) buildPluginConfig (plugin apiv2.ApisixRoutePlugin , namespace string , secrets map [types.NamespacedName ]* corev1 .Secret ) map [string ]any {
145155 config := make (map [string ]any )
146156 if len (plugin .Config .Raw ) > 0 {
147157 if err := json .Unmarshal (plugin .Config .Raw , & config ); err != nil {
@@ -181,13 +191,16 @@ func (t *Translator) addAuthenticationPlugins(rule apiv2.ApisixRouteHTTP, plugin
181191 }
182192}
183193
184- func (t * Translator ) buildRoute (ar * apiv2.ApisixRoute , service * adc.Service , rule apiv2.ApisixRouteHTTP , plugins adc.Plugins , timeout * adc.Timeout , vars adc.Vars ) {
194+ func (t * Translator ) buildRoute (ar * apiv2.ApisixRoute , service * adc.Service , rule apiv2.ApisixRouteHTTP , plugins adc.Plugins , timeout * adc.Timeout , vars adc.Vars , enableWebsocket * * bool ) {
185195 route := adc .NewDefaultRoute ()
186196 route .Name = adc .ComposeRouteName (ar .Namespace , ar .Name , rule .Name )
187197 route .ID = id .GenID (route .Name )
188198 route .Desc = "Created by apisix-ingress-controller, DO NOT modify it manually"
189199 route .Labels = label .GenLabel (ar )
190- route .EnableWebsocket = ptr .To (rule .Websocket )
200+ route .EnableWebsocket = rule .Websocket
201+ if route .EnableWebsocket == nil && * enableWebsocket != nil {
202+ route .EnableWebsocket = * enableWebsocket
203+ }
191204 route .FilterFunc = rule .Match .FilterFunc
192205 route .Hosts = rule .Match .Hosts
193206 route .Methods = rule .Match .Methods
@@ -204,7 +217,11 @@ func (t *Translator) buildRoute(ar *apiv2.ApisixRoute, service *adc.Service, rul
204217 service .Routes = []* adc.Route {route }
205218}
206219
220+ << << << < HEAD
207221func (t * Translator ) buildUpstream (tctx * provider.TranslateContext , service * adc.Service , ar * apiv2.ApisixRoute , rule apiv2.ApisixRouteHTTP , ruleIndex int ) {
222+ == == == =
223+ func (t * Translator ) buildUpstream (tctx * provider .TranslateContext , service * adc .Service , ar * apiv2 .ApisixRoute , rule apiv2 .ApisixRouteHTTP , enableWebsocket * * bool ) {
224+ >> >> >> > f28b3429 (feat : support resolve svc.ports [].appProtocol (#2601 ))
208225 var (
209226 upstreams = make ([]* adc.Upstream , 0 )
210227 weightedUpstreams = make ([]adc.TrafficSplitConfigRuleWeightedUpstream , 0 )
@@ -215,9 +232,16 @@ func (t *Translator) buildUpstream(tctx *provider.TranslateContext, service *adc
215232 upstream := adc .NewDefaultUpstream ()
216233 // try to get the apisixupstream with the same name as the backend service to be upstream config.
217234 // err is ignored because it does not care about the externalNodes of the apisixupstream.
235+ << << << < HEAD
218236 auNN := types.NamespacedName {Namespace : ar .GetNamespace (), Name : backend .ServiceName }
219237 if au , ok := tctx .Upstreams [auNN ]; ok {
220238 upstream , _ = t .translateApisixUpstream (tctx , au )
239+ == == == =
240+ upstream , err := t .translateApisixRouteHTTPBackend (tctx , ar , backend , enableWebsocket )
241+ if err != nil {
242+ t .Log .Error (err , "failed to translate ApisixRoute backend" , "backend" , backend )
243+ continue
244+ >> >> >> > f28b3429 (feat : support resolve svc.ports [].appProtocol (#2601 ))
221245 }
222246
223247 if backend .ResolveGranularity == apiv2 .ResolveGranularityService {
@@ -332,7 +356,7 @@ func (t *Translator) buildService(ar *apiv2.ApisixRoute, rule apiv2.ApisixRouteH
332356 return service
333357}
334358
335- func getPortFromService (svc * v1 .Service , backendSvcPort intstr.IntOrString ) (int32 , error ) {
359+ func getPortFromService (svc * corev1 .Service , backendSvcPort intstr.IntOrString ) (int32 , error ) {
336360 var port int32
337361 if backendSvcPort .Type == intstr .Int {
338362 port = int32 (backendSvcPort .IntValue ())
@@ -352,32 +376,107 @@ func getPortFromService(svc *v1.Service, backendSvcPort intstr.IntOrString) (int
352376 return port , nil
353377}
354378
379+ << << << < HEAD
355380func (t * Translator ) translateApisixRouteBackendResolveGranularityService (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteHTTPBackend ) (adc.UpstreamNodes , error ) {
381+ == == == =
382+ func findMatchingServicePort (svc * corev1 .Service , backendSvcPort intstr .IntOrString ) (* corev1 .ServicePort , error ) {
383+ var servicePort * corev1.ServicePort
384+ var portNumber int32 = - 1
385+ var servicePortName string
386+ switch backendSvcPort .Type {
387+ case intstr .Int :
388+ portNumber = backendSvcPort .IntVal
389+ case intstr .String :
390+ servicePortName = backendSvcPort .StrVal
391+ }
392+ for _ , svcPort := range svc .Spec .Ports {
393+ p := svcPort
394+ if p .Port == portNumber || (p .Name != "" && p .Name == servicePortName ) {
395+ servicePort = & p
396+ break
397+ }
398+ }
399+ if servicePort == nil {
400+ return nil , errors .Errorf ("service port %s not found in service %s" , backendSvcPort .String (), svc .Name )
401+ }
402+
403+ return servicePort , nil
404+ }
405+
406+ func (t * Translator ) translateApisixRouteHTTPBackend (tctx * provider .TranslateContext , ar * apiv2 .ApisixRoute , backend apiv2 .ApisixRouteHTTPBackend , enableWebsocket * * bool ) (* adc .Upstream , error ) {
407+ auNN := types.NamespacedName {
408+ Namespace : ar .Namespace ,
409+ Name : backend .ServiceName ,
410+ }
411+ upstream := adc .NewDefaultUpstream ()
412+ if au , ok := tctx .Upstreams [auNN ]; ok {
413+ svc := tctx .Services [auNN ]
414+ if svc == nil {
415+ return nil , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , utils .NamespacedName (ar ).String (), auNN )
416+ }
417+ port , err := getPortFromService (svc , backend .ServicePort )
418+ if err != nil {
419+ return nil , err
420+ }
421+ u , err := t .translateApisixUpstreamForPort (tctx , au , ptr .To (port ))
422+ if err != nil {
423+ return nil , err
424+ }
425+ upstream = u
426+ }
427+ var (
428+ err error
429+ nodes adc.UpstreamNodes
430+ protocol string
431+ )
432+ if backend .ResolveGranularity == apiv2 .ResolveGranularityService {
433+ nodes , protocol , err = t .translateApisixRouteBackendResolveGranularityService (tctx , auNN , backend )
434+ } else {
435+ nodes , protocol , err = t .translateApisixRouteBackendResolveGranularityEndpoint (tctx , auNN , backend )
436+ }
437+ if err != nil {
438+ return nil , err
439+ }
440+ upstream .Nodes = nodes
441+ if upstream .Scheme == "" {
442+ upstream .Scheme = appProtocolToUpstreamScheme (protocol )
443+ }
444+ if protocol == internaltypes .AppProtocolWS || protocol == internaltypes .AppProtocolWSS {
445+ * enableWebsocket = ptr .To (true )
446+ }
447+ if backend .Weight != nil {
448+ upstream .Labels ["meta_weight" ] = strconv .FormatInt (int64 (* backend .Weight ), 10 )
449+ }
450+ return upstream , nil
451+ }
452+
453+ func (t * Translator ) translateApisixRouteBackendResolveGranularityService (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteHTTPBackend ) (adc.UpstreamNodes , string , error ) {
454+ >> >> >> > f28b3429 (feat : support resolve svc.ports [].appProtocol (#2601 ))
356455 serviceNN := types.NamespacedName {
357456 Namespace : arNN .Namespace ,
358457 Name : backend .ServiceName ,
359458 }
360459 svc , ok := tctx .Services [serviceNN ]
361460 if ! ok {
362- return nil , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
461+ return nil , "" , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
363462 }
364463 if svc .Spec .ClusterIP == "" {
365- return nil , errors .Errorf ("conflict headless service and backend resolve granularity, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
464+ return nil , "" , errors .Errorf ("conflict headless service and backend resolve granularity, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
366465 }
367- port , err := getPortFromService (svc , backend .ServicePort )
466+ port , err := findMatchingServicePort (svc , backend .ServicePort )
368467 if err != nil {
369- return nil , err
468+ return nil , "" , err
370469 }
371470 return adc.UpstreamNodes {
372471 {
373472 Host : svc .Spec .ClusterIP ,
374- Port : int (port ),
473+ Port : int (port . Port ),
375474 Weight : * cmp .Or (backend .Weight , ptr .To (apiv2 .DefaultWeight )),
376475 },
377- }, nil
476+ }, ptr . Deref ( port . AppProtocol , "" ), nil
378477}
379478
380- func (t * Translator ) translateApisixRouteStreamBackendResolveGranularity (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteStreamBackend ) (adc.UpstreamNodes , error ) {
479+ func (t * Translator ) translateApisixRouteStreamBackendResolveGranularity (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteStreamBackend ) (adc.UpstreamNodes , string , error ) {
381480 tsBackend := apiv2.ApisixRouteHTTPBackend {
382481 ServiceName : backend .ServiceName ,
383482 ServicePort : backend .ServicePort ,
@@ -391,18 +490,18 @@ func (t *Translator) translateApisixRouteStreamBackendResolveGranularity(tctx *p
391490 }
392491}
393492
394- func (t * Translator ) translateApisixRouteBackendResolveGranularityEndpoint (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteHTTPBackend ) (adc.UpstreamNodes , error ) {
493+ func (t * Translator ) translateApisixRouteBackendResolveGranularityEndpoint (tctx * provider.TranslateContext , arNN types.NamespacedName , backend apiv2.ApisixRouteHTTPBackend ) (adc.UpstreamNodes , string , error ) {
395494 serviceNN := types.NamespacedName {
396495 Namespace : arNN .Namespace ,
397496 Name : backend .ServiceName ,
398497 }
399498 svc , ok := tctx .Services [serviceNN ]
400499 if ! ok {
401- return nil , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
500+ return nil , "" , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , arNN , serviceNN )
402501 }
403502 port , err := getPortFromService (svc , backend .ServicePort )
404503 if err != nil {
405- return nil , err
504+ return nil , "" , err
406505 }
407506 weight := int32 (* cmp .Or (backend .Weight , ptr .To (apiv2 .DefaultWeight )))
408507 backendRef := gatewayv1.BackendRef {
@@ -451,3 +550,32 @@ func (t *Translator) translateStreamRule(tctx *provider.TranslateContext, ar *ap
451550 svc .Upstream = upstream
452551 return svc , nil
453552}
553+ << << << < HEAD
554+ == == == =
555+
556+ func (t * Translator ) translateApisixRouteStreamBackend (tctx * provider.TranslateContext , ar * apiv2.ApisixRoute , backend apiv2.ApisixRouteStreamBackend ) (* adc.Upstream , error ) {
557+ auNN := types.NamespacedName {Namespace : ar .GetNamespace (), Name : backend .ServiceName }
558+ upstream := adc .NewDefaultUpstream ()
559+ if au , ok := tctx .Upstreams [auNN ]; ok {
560+ service := tctx .Services [auNN ]
561+ if service == nil {
562+ return nil , errors .Errorf ("service not found, ApisixRoute: %s, Service: %s" , utils .NamespacedName (ar ), auNN )
563+ }
564+ port , err := getPortFromService (service , backend .ServicePort )
565+ if err != nil {
566+ return nil , err
567+ }
568+ u , err := t .translateApisixUpstreamForPort (tctx , au , ptr .To (port ))
569+ if err != nil {
570+ return nil , err
571+ }
572+ upstream = u
573+ }
574+ nodes , _ , err := t .translateApisixRouteStreamBackendResolveGranularity (tctx , utils .NamespacedName (ar ), backend )
575+ if err != nil {
576+ return nil , err
577+ }
578+ upstream .Nodes = nodes
579+ return upstream , nil
580+ }
581+ >> >> >> > f28b3429 (feat : support resolve svc.ports [].appProtocol (#2601 ))
0 commit comments