@@ -100,6 +100,7 @@ type PushContext struct {
100
100
// exportedDestRulesByNamespace: all dest rules pertaining to a service exported by a namespace
101
101
namespaceLocalDestRules map [string ]* processedDestRules
102
102
exportedDestRulesByNamespace map [string ]* processedDestRules
103
+ rootNamespaceLocalDestRules * processedDestRules
103
104
104
105
// clusterLocalHosts extracted from the MeshConfig
105
106
clusterLocalHosts host.Names
@@ -702,6 +703,14 @@ func (ps *PushContext) DestinationRule(proxy *Proxy, service *Service) *Config {
702
703
return ps .namespaceLocalDestRules [proxy .ConfigNamespace ].destRule [hostname ]
703
704
}
704
705
}
706
+ } else {
707
+ // If this is a namespace local DR in the same namespace, this must be meant for this proxy, so we do not
708
+ // need to worry about overriding other DRs with *.local type rules here. If we ignore this, then exportTo=. in
709
+ // root namespace would always be ignored
710
+ if hostname , ok := MostSpecificHostMatch (service .Hostname ,
711
+ ps .rootNamespaceLocalDestRules .hosts ); ok {
712
+ return ps .rootNamespaceLocalDestRules .destRule [hostname ]
713
+ }
705
714
}
706
715
707
716
// 2. select destination rule from service namespace
@@ -729,7 +738,6 @@ func (ps *PushContext) DestinationRule(proxy *Proxy, service *Service) *Config {
729
738
730
739
// 4. if no public/private rule in calling proxy's namespace matched, and no public rule in the
731
740
// target service's namespace matched, search for any exported destination rule in the config root namespace
732
- // NOTE: This does mean that we are effectively ignoring private dest rules in the config root namespace
733
741
if out := ps .getExportedDestinationRuleFromNamespace (ps .Mesh .RootNamespace , service .Hostname , proxy .ConfigNamespace ); out != nil {
734
742
return out
735
743
}
@@ -927,6 +935,7 @@ func (ps *PushContext) updateContext(
927
935
} else {
928
936
ps .namespaceLocalDestRules = oldPushContext .namespaceLocalDestRules
929
937
ps .exportedDestRulesByNamespace = oldPushContext .exportedDestRulesByNamespace
938
+ ps .rootNamespaceLocalDestRules = oldPushContext .rootNamespaceLocalDestRules
930
939
}
931
940
932
941
if authnChanged {
@@ -1303,6 +1312,14 @@ func (ps *PushContext) initDestinationRules(env *Environment) error {
1303
1312
return nil
1304
1313
}
1305
1314
1315
+ func newProcessedDestRules () * processedDestRules {
1316
+ return & processedDestRules {
1317
+ hosts : make ([]host.Name , 0 ),
1318
+ exportTo : map [host.Name ]map [visibility.Instance ]bool {},
1319
+ destRule : map [host.Name ]* Config {},
1320
+ }
1321
+ }
1322
+
1306
1323
// SetDestinationRules is updates internal structures using a set of configs.
1307
1324
// Split out of DestinationRule expensive conversions, computed once per push.
1308
1325
// This also allows tests to inject a config without having the mock.
@@ -1313,6 +1330,7 @@ func (ps *PushContext) SetDestinationRules(configs []Config) {
1313
1330
sortConfigByCreationTime (configs )
1314
1331
namespaceLocalDestRules := make (map [string ]* processedDestRules )
1315
1332
exportedDestRulesByNamespace := make (map [string ]* processedDestRules )
1333
+ rootNamespaceLocalDestRules := newProcessedDestRules ()
1316
1334
1317
1335
for i := range configs {
1318
1336
rule := configs [i ].Spec .(* networking.DestinationRule )
@@ -1329,11 +1347,7 @@ func (ps *PushContext) SetDestinationRules(configs []Config) {
1329
1347
// a proxy from this namespace will first look here for the destination rule for a given service
1330
1348
// This pool consists of both public/private destination rules.
1331
1349
if _ , exist := namespaceLocalDestRules [configs [i ].Namespace ]; ! exist {
1332
- namespaceLocalDestRules [configs [i ].Namespace ] = & processedDestRules {
1333
- hosts : make ([]host.Name , 0 ),
1334
- exportTo : map [host.Name ]map [visibility.Instance ]bool {},
1335
- destRule : map [host.Name ]* Config {},
1336
- }
1350
+ namespaceLocalDestRules [configs [i ].Namespace ] = newProcessedDestRules ()
1337
1351
}
1338
1352
// Merge this destination rule with any public/private dest rules for same host in the same namespace
1339
1353
// If there are no duplicates, the dest rule will be added to the list
@@ -1351,15 +1365,14 @@ func (ps *PushContext) SetDestinationRules(configs []Config) {
1351
1365
1352
1366
if ! isPrivateOnly {
1353
1367
if _ , exist := exportedDestRulesByNamespace [configs [i ].Namespace ]; ! exist {
1354
- exportedDestRulesByNamespace [configs [i ].Namespace ] = & processedDestRules {
1355
- hosts : make ([]host.Name , 0 ),
1356
- exportTo : map [host.Name ]map [visibility.Instance ]bool {},
1357
- destRule : map [host.Name ]* Config {},
1358
- }
1368
+ exportedDestRulesByNamespace [configs [i ].Namespace ] = newProcessedDestRules ()
1359
1369
}
1360
1370
// Merge this destination rule with any other exported dest rule for the same host in the same namespace
1361
1371
// If there are no duplicates, the dest rule will be added to the list
1362
1372
ps .mergeDestinationRule (exportedDestRulesByNamespace [configs [i ].Namespace ], configs [i ], exportToMap )
1373
+ } else if configs [i ].Namespace == ps .Mesh .RootNamespace {
1374
+ // Keep track of private root namespace destination rules
1375
+ ps .mergeDestinationRule (rootNamespaceLocalDestRules , configs [i ], exportToMap )
1363
1376
}
1364
1377
}
1365
1378
@@ -1374,6 +1387,7 @@ func (ps *PushContext) SetDestinationRules(configs []Config) {
1374
1387
1375
1388
ps .namespaceLocalDestRules = namespaceLocalDestRules
1376
1389
ps .exportedDestRulesByNamespace = exportedDestRulesByNamespace
1390
+ ps .rootNamespaceLocalDestRules = rootNamespaceLocalDestRules
1377
1391
}
1378
1392
1379
1393
func (ps * PushContext ) initAuthorizationPolicies (env * Environment ) error {
0 commit comments