@@ -16,13 +16,14 @@ func TestBuildHTTPRoutes(t *testing.T) {
1616 pathExact := networking .PathTypeExact
1717
1818 tests := []struct {
19- name string
20- ing networking.Ingress
21- namespace string
22- gwName string
23- ports []listenPortEntry
24- wantRoutes int
25- check func (t * testing.T , routes []gwv1.HTTPRoute )
19+ name string
20+ ing networking.Ingress
21+ namespace string
22+ gwName string
23+ ports []listenPortEntry
24+ sslRedirectPort * int32
25+ wantRoutes int
26+ check func (t * testing.T , routes []gwv1.HTTPRoute )
2627 }{
2728 {
2829 name : "single rule with host and prefix path" ,
@@ -439,11 +440,65 @@ func TestBuildHTTPRoutes(t *testing.T) {
439440 assert .Equal (t , "/src" , * r .Spec .Rules [0 ].Matches [0 ].Path .Value )
440441 },
441442 },
443+ {
444+ name : "ssl-redirect produces redirect route on HTTP and rules route on HTTPS" ,
445+ ing : networking.Ingress {
446+ ObjectMeta : metav1.ObjectMeta {
447+ Name : "ssl" ,
448+ Annotations : map [string ]string {
449+ "alb.ingress.kubernetes.io/ssl-redirect" : "443" ,
450+ },
451+ },
452+ Spec : networking.IngressSpec {
453+ Rules : []networking.IngressRule {{
454+ Host : "app.example.com" ,
455+ IngressRuleValue : networking.IngressRuleValue {
456+ HTTP : & networking.HTTPIngressRuleValue {
457+ Paths : []networking.HTTPIngressPath {{
458+ Path : "/api" , PathType : & pathPrefix ,
459+ Backend : networking.IngressBackend {
460+ Service : & networking.IngressServiceBackend {
461+ Name : "api-svc" , Port : networking.ServiceBackendPort {Number : 80 },
462+ },
463+ },
464+ }},
465+ },
466+ },
467+ }},
468+ },
469+ },
470+ namespace : "default" , gwName : "gw" ,
471+ ports : []listenPortEntry {
472+ {Protocol : "HTTP" , Port : 80 },
473+ {Protocol : "HTTPS" , Port : 443 },
474+ },
475+ sslRedirectPort : int32Ptr (443 ),
476+ wantRoutes : 2 , // rules route + redirect route
477+ check : func (t * testing.T , routes []gwv1.HTTPRoute ) {
478+ // First route: rules, attached to HTTPS listener only
479+ rulesRoute := routes [0 ]
480+ require .NotNil (t , rulesRoute .Spec .ParentRefs [0 ].SectionName )
481+ assert .Equal (t , gwv1 .SectionName ("https-443" ), * rulesRoute .Spec .ParentRefs [0 ].SectionName )
482+ assert .Len (t , rulesRoute .Spec .Rules , 1 )
483+ assert .Equal (t , "/api" , * rulesRoute .Spec .Rules [0 ].Matches [0 ].Path .Value )
484+
485+ // Second route: redirect, attached to HTTP listener only
486+ redirectRoute := routes [1 ]
487+ require .NotNil (t , redirectRoute .Spec .ParentRefs [0 ].SectionName )
488+ assert .Equal (t , gwv1 .SectionName ("http-80" ), * redirectRoute .Spec .ParentRefs [0 ].SectionName )
489+ require .Len (t , redirectRoute .Spec .Rules , 1 )
490+ require .Len (t , redirectRoute .Spec .Rules [0 ].Filters , 1 )
491+ assert .Equal (t , gwv1 .HTTPRouteFilterRequestRedirect , redirectRoute .Spec .Rules [0 ].Filters [0 ].Type )
492+ assert .Equal (t , "https" , * redirectRoute .Spec .Rules [0 ].Filters [0 ].RequestRedirect .Scheme )
493+ assert .Equal (t , gwv1 .PortNumber (443 ), * redirectRoute .Spec .Rules [0 ].Filters [0 ].RequestRedirect .Port )
494+ assert .Equal (t , 301 , * redirectRoute .Spec .Rules [0 ].Filters [0 ].RequestRedirect .StatusCode )
495+ },
496+ },
442497 }
443498
444499 for _ , tt := range tests {
445500 t .Run (tt .name , func (t * testing.T ) {
446- routes , _ , _ , err := buildHTTPRoutes (tt .ing , tt .namespace , tt .gwName , tt .ports , nil )
501+ routes , _ , _ , err := buildHTTPRoutes (tt .ing , tt .namespace , tt .gwName , tt .ports , nil , tt . sslRedirectPort )
447502 require .NoError (t , err )
448503 require .Len (t , routes , tt .wantRoutes )
449504 if tt .check != nil {
@@ -525,3 +580,39 @@ func TestResolveServicePort(t *testing.T) {
525580 _ , err = resolveServicePort (networking.ServiceBackendPort {}, "default" , "my-svc" , svcMap )
526581 assert .Error (t , err )
527582}
583+
584+ func int32Ptr (v int32 ) * int32 { return & v }
585+
586+ func TestBuildHTTPRoutes_DefaultBackendError (t * testing.T ) {
587+ pathPrefix := networking .PathTypePrefix
588+ ing := networking.Ingress {
589+ ObjectMeta : metav1.ObjectMeta {Name : "app" },
590+ Spec : networking.IngressSpec {
591+ DefaultBackend : & networking.IngressBackend {
592+ Service : & networking.IngressServiceBackend {
593+ Name : "missing-svc" ,
594+ Port : networking.ServiceBackendPort {Name : "http" },
595+ },
596+ },
597+ Rules : []networking.IngressRule {{
598+ IngressRuleValue : networking.IngressRuleValue {
599+ HTTP : & networking.HTTPIngressRuleValue {
600+ Paths : []networking.HTTPIngressPath {{
601+ Path : "/" , PathType : & pathPrefix ,
602+ Backend : networking.IngressBackend {
603+ Service : & networking.IngressServiceBackend {
604+ Name : "svc" , Port : networking.ServiceBackendPort {Number : 80 },
605+ },
606+ },
607+ }},
608+ },
609+ },
610+ }},
611+ },
612+ }
613+ // No services provided — named port resolution for defaultBackend will fail
614+ _ , _ , _ , err := buildHTTPRoutes (ing , "default" , "gw" ,
615+ []listenPortEntry {{Protocol : "HTTP" , Port : 80 }}, nil , nil )
616+ assert .Error (t , err )
617+ assert .Contains (t , err .Error (), "defaultBackend" )
618+ }
0 commit comments