istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/xds/lds.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 discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" 19 20 "istio.io/istio/pilot/pkg/model" 21 "istio.io/istio/pilot/pkg/networking/core" 22 "istio.io/istio/pilot/pkg/util/protoconv" 23 "istio.io/istio/pkg/config/schema/kind" 24 "istio.io/istio/pkg/util/sets" 25 ) 26 27 type LdsGenerator struct { 28 ConfigGenerator core.ConfigGenerator 29 } 30 31 var _ model.XdsResourceGenerator = &LdsGenerator{} 32 33 // Map of all configs that do not impact LDS 34 var skippedLdsConfigs = map[model.NodeType]sets.Set[kind.Kind]{ 35 model.Router: sets.New( 36 // for autopassthrough gateways, we build filterchains per-dr subset 37 kind.WorkloadGroup, 38 kind.WorkloadEntry, 39 kind.Secret, 40 kind.ProxyConfig, 41 kind.DNSName, 42 ), 43 model.SidecarProxy: sets.New( 44 kind.Gateway, 45 kind.WorkloadGroup, 46 kind.WorkloadEntry, 47 kind.Secret, 48 kind.ProxyConfig, 49 kind.DNSName, 50 51 kind.KubernetesGateway, 52 ), 53 model.Waypoint: sets.New( 54 kind.Gateway, 55 kind.WorkloadGroup, 56 kind.WorkloadEntry, 57 kind.Secret, 58 kind.ProxyConfig, 59 kind.DNSName, 60 61 kind.KubernetesGateway, 62 ), 63 } 64 65 func ldsNeedsPush(proxy *model.Proxy, req *model.PushRequest) bool { 66 if req == nil { 67 return true 68 } 69 switch proxy.Type { 70 case model.Waypoint: 71 if model.HasConfigsOfKind(req.ConfigsUpdated, kind.Address) { 72 // Waypoint proxies have a matcher against pod IPs in them. Historically, any LDS change would do a full 73 // push, recomputing push context. Doing that on every IP change doesn't scale, so we need these to remain 74 // incremental pushes. 75 // This allows waypoints only to push LDS on incremental pushes to Address type which would otherwise be skipped. 76 return true 77 } 78 // Otherwise, only handle full pushes (skip endpoint-only updates) 79 if !req.Full { 80 return false 81 } 82 default: 83 if !req.Full { 84 // LDS only handles full push 85 return false 86 } 87 } 88 // If none set, we will always push 89 if len(req.ConfigsUpdated) == 0 { 90 return true 91 } 92 for config := range req.ConfigsUpdated { 93 if !skippedLdsConfigs[proxy.Type].Contains(config.Kind) { 94 return true 95 } 96 } 97 return false 98 } 99 100 func (l LdsGenerator) Generate(proxy *model.Proxy, _ *model.WatchedResource, req *model.PushRequest) (model.Resources, model.XdsLogDetails, error) { 101 if !ldsNeedsPush(proxy, req) { 102 return nil, model.DefaultXdsLogDetails, nil 103 } 104 listeners := l.ConfigGenerator.BuildListeners(proxy, req.Push) 105 resources := model.Resources{} 106 for _, c := range listeners { 107 resources = append(resources, &discovery.Resource{ 108 Name: c.Name, 109 Resource: protoconv.MessageToAny(c), 110 }) 111 } 112 return resources, model.DefaultXdsLogDetails, nil 113 }