func()

in pilot/pkg/model/push_context.go [1732:1825]


func (ps *PushContext) SetDestinationRules(configs []config.Config) {
	// Sort by time first. So if two destination rule have top level traffic policies
	// we take the first one.
	sortConfigByCreationTime(configs)
	namespaceLocalDestRules := make(map[string]*consolidatedDestRules)
	exportedDestRulesByNamespace := make(map[string]*consolidatedDestRules)
	rootNamespaceLocalDestRules := newConsolidatedDestRules()
	inheritedConfigs := make(map[string]*consolidatedDestRule)

	for i := range configs {
		rule := configs[i].Spec.(*networking.DestinationRule)

		if features.EnableDestinationRuleInheritance && rule.Host == "" {
			if t, ok := inheritedConfigs[configs[i].Namespace]; ok {
				log.Warnf("Namespace/mesh-level DestinationRule is already defined for %q at time %v."+
					" Ignore %q which was created at time %v",
					configs[i].Namespace, t.rule.CreationTimestamp, configs[i].Name, configs[i].CreationTimestamp)
				continue
			}
			inheritedConfigs[configs[i].Namespace] = convertConsolidatedDestRule(&configs[i])
		}

		rule.Host = string(ResolveShortnameToFQDN(rule.Host, configs[i].Meta))
		exportToMap := make(map[visibility.Instance]bool)

		// destination rules with workloadSelector should not be exported to other namespaces
		if rule.GetWorkloadSelector() == nil {
			for _, e := range rule.ExportTo {
				exportToMap[visibility.Instance(e)] = true
			}
		} else {
			exportToMap[visibility.Private] = true
		}

		// add only if the dest rule is exported with . or * or explicit exportTo containing this namespace
		// The global exportTo doesn't matter here (its either . or * - both of which are applicable here)
		if len(exportToMap) == 0 || exportToMap[visibility.Public] || exportToMap[visibility.Private] ||
			exportToMap[visibility.Instance(configs[i].Namespace)] {
			// Store in an index for the config's namespace
			// a proxy from this namespace will first look here for the destination rule for a given service
			// This pool consists of both public/private destination rules.
			if _, exist := namespaceLocalDestRules[configs[i].Namespace]; !exist {
				namespaceLocalDestRules[configs[i].Namespace] = newConsolidatedDestRules()
			}
			// Merge this destination rule with any public/private dest rules for same host in the same namespace
			// If there are no duplicates, the dest rule will be added to the list
			ps.mergeDestinationRule(namespaceLocalDestRules[configs[i].Namespace], configs[i], exportToMap)
		}

		isPrivateOnly := false
		// No exportTo in destinationRule. Use the global default
		// We only honor . and *
		if len(exportToMap) == 0 && ps.exportToDefaults.destinationRule[visibility.Private] {
			isPrivateOnly = true
		} else if len(exportToMap) == 1 && (exportToMap[visibility.Private] || exportToMap[visibility.Instance(configs[i].Namespace)]) {
			isPrivateOnly = true
		}

		if !isPrivateOnly {
			if _, exist := exportedDestRulesByNamespace[configs[i].Namespace]; !exist {
				exportedDestRulesByNamespace[configs[i].Namespace] = newConsolidatedDestRules()
			}
			// Merge this destination rule with any other exported dest rule for the same host in the same namespace
			// If there are no duplicates, the dest rule will be added to the list
			ps.mergeDestinationRule(exportedDestRulesByNamespace[configs[i].Namespace], configs[i], exportToMap)
		} else if configs[i].Namespace == ps.Mesh.RootNamespace {
			// Keep track of private root namespace destination rules
			ps.mergeDestinationRule(rootNamespaceLocalDestRules, configs[i], exportToMap)
		}
	}

	// precompute DestinationRules with inherited fields
	if features.EnableDestinationRuleInheritance {
		globalRule := inheritedConfigs[ps.Mesh.RootNamespace]
		for ns := range namespaceLocalDestRules {
			nsRule := inheritedConfigs[ns]
			inheritedRule := ps.inheritDestinationRule(globalRule, nsRule)
			for hostname, cfgList := range namespaceLocalDestRules[ns].destRules {
				for i, cfg := range cfgList {
					namespaceLocalDestRules[ns].destRules[hostname][i] = ps.inheritDestinationRule(inheritedRule, cfg)
				}
			}
			// update namespace rule after it has been merged with mesh rule
			inheritedConfigs[ns] = inheritedRule
		}
		// can't precalculate exportedDestRulesByNamespace since we don't know all the client namespaces in advance
		// inheritance is performed in getExportedDestinationRuleFromNamespace
	}

	ps.destinationRuleIndex.namespaceLocal = namespaceLocalDestRules
	ps.destinationRuleIndex.exportedByNamespace = exportedDestRulesByNamespace
	ps.destinationRuleIndex.rootNamespaceLocal = rootNamespaceLocalDestRules
	ps.destinationRuleIndex.inheritedByNamespace = inheritedConfigs
}