istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/xds/proxy_dependencies.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package xds 16 17 import ( 18 "istio.io/istio/pilot/pkg/features" 19 "istio.io/istio/pilot/pkg/model" 20 "istio.io/istio/pkg/config/host" 21 "istio.io/istio/pkg/config/schema/kind" 22 "istio.io/istio/pkg/util/sets" 23 ) 24 25 // UnAffectedConfigKinds contains config types which does not affect certain proxy types. 26 var UnAffectedConfigKinds = map[model.NodeType]sets.Set[kind.Kind]{ 27 // For Gateways, we do not care about the following configs for example Sidecar. 28 model.Router: sets.New(kind.Sidecar), 29 // For Sidecar, we do not care about the following configs for example Gateway. 30 model.SidecarProxy: sets.New(kind.Gateway, kind.KubernetesGateway), 31 } 32 33 // ConfigAffectsProxy checks if a pushEv will affect a specified proxy. That means whether the push will be performed 34 // towards the proxy. 35 func ConfigAffectsProxy(req *model.PushRequest, proxy *model.Proxy) bool { 36 // Empty changes means "all" to get a backward compatibility. 37 if len(req.ConfigsUpdated) == 0 { 38 return true 39 } 40 if proxy.IsWaypointProxy() || proxy.IsZTunnel() { 41 // Optimizations do not apply since scoping uses different mechanism 42 // TODO: implement ambient aware scoping 43 return true 44 } 45 46 for config := range req.ConfigsUpdated { 47 if proxyDependentOnConfig(proxy, config, req.Push) { 48 return true 49 } 50 } 51 52 return false 53 } 54 55 func proxyDependentOnConfig(proxy *model.Proxy, config model.ConfigKey, push *model.PushContext) bool { 56 // Skip config dependency check based on proxy type for certain configs. 57 if UnAffectedConfigKinds[proxy.Type].Contains(config.Kind) { 58 return false 59 } 60 // Detailed config dependencies check. 61 switch proxy.Type { 62 case model.SidecarProxy: 63 if proxy.SidecarScope.DependsOnConfig(config, push.Mesh.RootNamespace) { 64 return true 65 } else if proxy.PrevSidecarScope != nil && proxy.PrevSidecarScope.DependsOnConfig(config, push.Mesh.RootNamespace) { 66 return true 67 } 68 case model.Router: 69 if config.Kind == kind.ServiceEntry { 70 // If config is ServiceEntry, name of the config is service's FQDN 71 if features.FilterGatewayClusterConfig && !push.ServiceAttachedToGateway(config.Name, proxy) { 72 return false 73 } 74 75 hostname := host.Name(config.Name) 76 // gateways have default sidecar scopes 77 if proxy.SidecarScope.GetService(hostname) == nil && 78 proxy.PrevSidecarScope.GetService(hostname) == nil { 79 // skip the push when the service is not visible to the gateway, 80 // and the old service is not visible/existent 81 return false 82 } 83 } 84 return true 85 default: 86 // TODO We'll add the check for other proxy types later. 87 return true 88 } 89 return false 90 } 91 92 // DefaultProxyNeedsPush check if a proxy needs push for this push event. 93 func DefaultProxyNeedsPush(proxy *model.Proxy, req *model.PushRequest) bool { 94 if ConfigAffectsProxy(req, proxy) { 95 return true 96 } 97 98 // If the proxy's service updated, need push for it. 99 if len(proxy.ServiceTargets) > 0 && req.ConfigsUpdated != nil { 100 for _, svc := range proxy.ServiceTargets { 101 if _, ok := req.ConfigsUpdated[model.ConfigKey{ 102 Kind: kind.ServiceEntry, 103 Name: string(svc.Service.Hostname), 104 Namespace: svc.Service.Attributes.Namespace, 105 }]; ok { 106 return true 107 } 108 } 109 } 110 111 return false 112 }