@@ -301,6 +301,9 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
301301 }
302302
303303 hostMatch := hostWithoutPort (model .ExternalHost )
304+ configBasePaths := configPathVariants ("/config/" + namespace )
305+ servicesBasePaths := configPathVariants ("/config/" + namespace + "/services" )
306+ transformationsBasePaths := configPathVariants ("/config/" + namespace + "/transformations" )
304307
305308 irName := "aggregator-instance-ingressroute"
306309 obj := & unstructured.Unstructured {
@@ -315,7 +318,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
315318 "entryPoints" : []string {"web" },
316319 "routes" : []interface {}{
317320 map [string ]interface {}{
318- "match" : "Host(`" + hostMatch + "`) && (Path(`/config/ " + namespace + "`) || Path(`/config/" + namespace + "/`)) && Method(`OPTIONS`)" ,
321+ "match" : "Host(`" + hostMatch + "`) && " + exactPathRule ( configBasePaths ) + " && Method(`OPTIONS`)" ,
319322 "kind" : "Rule" ,
320323 "services" : []interface {}{
321324 map [string ]interface {}{
@@ -327,7 +330,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
327330 "middlewares" : buildCorsOnlyMiddlewares (namespace , true ),
328331 },
329332 map [string ]interface {}{
330- "match" : "Host(`" + hostMatch + "`) && (Path(`/config/ " + namespace + "`) || Path(`/config/" + namespace + "/`))" ,
333+ "match" : "Host(`" + hostMatch + "`) && " + exactPathRule ( configBasePaths ) ,
331334 "kind" : "Rule" ,
332335 "services" : []interface {}{
333336 map [string ]interface {}{
@@ -339,7 +342,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
339342 "middlewares" : buildIngressMiddlewares (useUMA , namespace , true ),
340343 },
341344 map [string ]interface {}{
342- "match" : "Host(`" + hostMatch + "`) && PathPrefix(`/config/ " + namespace + "/services`) && Method(`OPTIONS`)" ,
345+ "match" : "Host(`" + hostMatch + "`) && " + prefixPathRule ( servicesBasePaths ) + " && Method(`OPTIONS`)" ,
343346 "kind" : "Rule" ,
344347 "services" : []interface {}{
345348 map [string ]interface {}{
@@ -351,7 +354,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
351354 "middlewares" : buildCorsOnlyMiddlewares (namespace , false ),
352355 },
353356 map [string ]interface {}{
354- "match" : "Host(`" + hostMatch + "`) && PathPrefix(`/config/ " + namespace + "/services`)" ,
357+ "match" : "Host(`" + hostMatch + "`) && " + prefixPathRule ( servicesBasePaths ) ,
355358 "kind" : "Rule" ,
356359 "services" : []interface {}{
357360 map [string ]interface {}{
@@ -363,7 +366,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
363366 "middlewares" : buildIngressMiddlewares (useUMA , namespace , false ),
364367 },
365368 map [string ]interface {}{
366- "match" : "Host(`" + hostMatch + "`) && PathPrefix(`/config/ " + namespace + "/transformations`) && Method(`OPTIONS`)" ,
369+ "match" : "Host(`" + hostMatch + "`) && " + prefixPathRule ( transformationsBasePaths ) + " && Method(`OPTIONS`)" ,
367370 "kind" : "Rule" ,
368371 "services" : []interface {}{
369372 map [string ]interface {}{
@@ -375,7 +378,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
375378 "middlewares" : buildCorsOnlyMiddlewares (namespace , true ),
376379 },
377380 map [string ]interface {}{
378- "match" : "Host(`" + hostMatch + "`) && PathPrefix(`/config/ " + namespace + "/transformations`)" ,
381+ "match" : "Host(`" + hostMatch + "`) && " + prefixPathRule ( transformationsBasePaths ) ,
379382 "kind" : "Rule" ,
380383 "services" : []interface {}{
381384 map [string ]interface {}{
@@ -408,7 +411,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
408411 },
409412 "spec" : map [string ]interface {}{
410413 "stripPrefix" : map [string ]interface {}{
411- "prefixes" : [] string { "/config/" + namespace } ,
414+ "prefixes" : configBasePaths ,
412415 },
413416 },
414417 },
@@ -565,6 +568,45 @@ func hostWithoutPort(hostport string) string {
565568 return hostport
566569}
567570
571+ func configPathVariants (path string ) []string {
572+ paths := []string {path }
573+ base := strings .TrimSuffix (model .ExternalBasePath , "/" )
574+ if base != "" {
575+ paths = append (paths , base + path )
576+ }
577+ return uniqueStrings (paths )
578+ }
579+
580+ func exactPathRule (paths []string ) string {
581+ rules := make ([]string , 0 , len (paths )* 2 )
582+ for _ , p := range paths {
583+ rules = append (rules , "Path(`" + p + "`)" )
584+ rules = append (rules , "Path(`" + p + "/`)" )
585+ }
586+ return "(" + strings .Join (rules , " || " ) + ")"
587+ }
588+
589+ func prefixPathRule (paths []string ) string {
590+ rules := make ([]string , 0 , len (paths ))
591+ for _ , p := range paths {
592+ rules = append (rules , "PathPrefix(`" + p + "`)" )
593+ }
594+ return "(" + strings .Join (rules , " || " ) + ")"
595+ }
596+
597+ func uniqueStrings (values []string ) []string {
598+ seen := map [string ]struct {}{}
599+ out := make ([]string , 0 , len (values ))
600+ for _ , value := range values {
601+ if _ , ok := seen [value ]; ok {
602+ continue
603+ }
604+ seen [value ] = struct {}{}
605+ out = append (out , value )
606+ }
607+ return out
608+ }
609+
568610func buildIngressMiddlewares (useUMA bool , namespace string , includeStrip bool ) []interface {} {
569611 middlewares := make ([]interface {}, 0 , 3 )
570612 middlewares = append (middlewares , map [string ]interface {}{
0 commit comments