@@ -3,6 +3,7 @@ package ingress
3
3
import (
4
4
"context"
5
5
"fmt"
6
+ "sort"
6
7
"strings"
7
8
8
9
"github.com/pkg/errors"
@@ -24,7 +25,11 @@ func (t *defaultModelBuildTask) buildListenerRules(ctx context.Context, lsARN co
24
25
if rule .HTTP == nil {
25
26
continue
26
27
}
27
- for _ , path := range rule .HTTP .Paths {
28
+ paths , err := t .sortIngressPaths (rule .HTTP .Paths )
29
+ if err != nil {
30
+ return err
31
+ }
32
+ for _ , path := range paths {
28
33
enhancedBackend , err := t .enhancedBackendBuilder .Build (ctx , ing .Ing , path .Backend ,
29
34
WithLoadBackendServices (true , t .backendServices ),
30
35
WithLoadAuthConfig (true ))
@@ -72,6 +77,48 @@ func (t *defaultModelBuildTask) buildListenerRules(ctx context.Context, lsARN co
72
77
return nil
73
78
}
74
79
80
+ // sortIngressPaths will sort the paths following the strategy:
81
+ // all exact match paths come first, no need to sort since exact match has to be unique
82
+ // followed by prefix paths, sort by lengths - longer paths get precedence
83
+ // followed by ImplementationSpecific paths or paths with no pathType specified, keep the original order
84
+ func (t * defaultModelBuildTask ) sortIngressPaths (paths []networking.HTTPIngressPath ) ([]networking.HTTPIngressPath , error ) {
85
+ exactPaths , prefixPaths , implementationSpecificPaths , err := t .classifyIngressPathsByType (paths )
86
+ if err != nil {
87
+ return nil , err
88
+ }
89
+ sortedPaths := exactPaths
90
+ sort .SliceStable (prefixPaths , func (i , j int ) bool {
91
+ return len (prefixPaths [i ].Path ) > len (prefixPaths [j ].Path )
92
+ })
93
+ sortedPaths = append (sortedPaths , prefixPaths ... )
94
+ sortedPaths = append (sortedPaths , implementationSpecificPaths ... )
95
+ return sortedPaths , nil
96
+ }
97
+
98
+ // classifyIngressPathsByType will classify the paths by type Exact, Prefix and ImplementationSpecific
99
+ func (t * defaultModelBuildTask ) classifyIngressPathsByType (paths []networking.HTTPIngressPath ) ([]networking.HTTPIngressPath , []networking.HTTPIngressPath , []networking.HTTPIngressPath , error ) {
100
+ var exactPaths []networking.HTTPIngressPath
101
+ var prefixPaths []networking.HTTPIngressPath
102
+ var implementationSpecificPaths []networking.HTTPIngressPath
103
+ for _ , path := range paths {
104
+ if path .PathType != nil {
105
+ switch * path .PathType {
106
+ case networking .PathTypeExact :
107
+ exactPaths = append (exactPaths , path )
108
+ case networking .PathTypePrefix :
109
+ prefixPaths = append (prefixPaths , path )
110
+ case networking .PathTypeImplementationSpecific :
111
+ implementationSpecificPaths = append (implementationSpecificPaths , path )
112
+ default :
113
+ return nil , nil , nil , errors .Errorf ("unknown pathType for path %s" , path .Path )
114
+ }
115
+ } else {
116
+ implementationSpecificPaths = append (implementationSpecificPaths , path )
117
+ }
118
+ }
119
+ return exactPaths , prefixPaths , implementationSpecificPaths , nil
120
+ }
121
+
75
122
func (t * defaultModelBuildTask ) buildRuleConditions (ctx context.Context , rule networking.IngressRule ,
76
123
path networking.HTTPIngressPath , backend EnhancedBackend ) ([]elbv2model.RuleCondition , error ) {
77
124
var hosts []string
0 commit comments