44 "fmt"
55
66 envoy_config_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
7+ envoy_config_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
78 "github.com/solo-io/gloo/projects/gateway2/krtcollections"
89 ggv2utils "github.com/solo-io/gloo/projects/gateway2/utils"
910 "github.com/solo-io/gloo/projects/gloo/pkg/xds"
@@ -42,31 +43,42 @@ func snapshotPerClient(l *zap.Logger, dbg *krt.DebugHandler, uccCol krt.Collecti
4243 return nil
4344 }
4445
46+ listenersProto := make ([]envoycache.Resource , 0 )
4547 clustersProto := make ([]envoycache.Resource , 0 , len (clustersForUcc ))
48+
4649 var clustersHash uint64
50+ var listenersHash uint64
51+
52+ // add the clusters and the additional resources created for them
4753 for _ , ep := range clustersForUcc {
4854 clustersProto = append (clustersProto , ep .Cluster )
49- clustersHash ^= ep .ClusterVersion
50- }
51- clustersVersion := fmt .Sprintf ("%d" , clustersHash )
5255
53- endpointsForUcc := endpoints .FetchEndpointsForClient (kctx , ucc )
54- endpointsProto := make ([]envoycache.Resource , 0 , len (endpointsForUcc ))
55- var endpointsHash uint64
56- for _ , ep := range endpointsForUcc {
57- endpointsProto = append (endpointsProto , ep .Endpoints )
58- endpointsHash ^= ep .EndpointsHash
56+ // add additional clusters
57+ for _ , additionalCluster := range ep .AdditionalClusters {
58+ clustersProto = append (clustersProto , additionalCluster )
59+ }
60+
61+ // add additional listeners
62+ for _ , additionalListener := range ep .AdditionalListeners {
63+ listenersProto = append (listenersProto , additionalListener )
64+ }
65+
66+ clustersHash ^= ep .ClusterVersion
67+ clustersHash ^= ep .AdditionalClustersHash
68+ listenersHash ^= ep .AdditionalListenersHash
5969 }
6070
61- mostlySnap := * maybeMostlySnap
71+ clusterResources := envoycache . NewResources ( fmt . Sprintf ( "%d" , clustersHash ), clustersProto )
6272
63- clusterResources := envoycache .NewResources (clustersVersion , clustersProto )
6473 // add missing generated resource from GeneratedResources plugins.
6574 // To be able to do individual upstream translation, We need to redo the GeneratedResources,
6675 // so they don't take as input the entire xds snapshot. the main offender is the tunneling plugin.
6776 //
6877 // for now, a manual audit showed that these only add clusters and listeners. As we don't touch the listeners,
6978 // we just need to account for potentially missing clusters.
79+ //
80+ // This can be removed once we have moved off GeneratedResources in favor of
81+ // UpstreamGeneratedResources which is krt-safe
7082 for name , cluster := range genericSnap .Clusters .Items {
7183 // only copy clusters that don't exist. as we do cluster translation per client,
7284 // our clusters might be slightly different.
@@ -77,13 +89,37 @@ func snapshotPerClient(l *zap.Logger, dbg *krt.DebugHandler, uccCol krt.Collecti
7789 }
7890 clusterResources .Version = fmt .Sprintf ("%d" , clustersHash )
7991
92+ listenerResources := envoycache .NewResources (fmt .Sprintf ("%d" , listenersHash ), listenersProto )
93+
94+ // add the snapshot listeners
95+ for name , listener := range genericSnap .Listeners .Items {
96+ // only copy listeners that don't exist. as we do cluster translation per client,
97+ // our clusters might be slightly different.
98+ if _ , ok := listenerResources .Items [name ]; ! ok {
99+ listenerResources .Items [name ] = listener
100+ listenersHash ^= ggv2utils .HashProto (listener .ResourceProto ().(* envoy_config_listener_v3.Listener ))
101+ }
102+ }
103+ listenerResources .Version = fmt .Sprintf ("%d" , listenersHash )
104+
105+ endpointsForUcc := endpoints .FetchEndpointsForClient (kctx , ucc )
106+ endpointsProto := make ([]envoycache.Resource , 0 , len (endpointsForUcc ))
107+ var endpointsHash uint64
108+ for _ , ep := range endpointsForUcc {
109+ endpointsProto = append (endpointsProto , ep .Endpoints )
110+ endpointsHash ^= ep .EndpointsHash
111+ }
112+ endpointResources := envoycache .NewResources (fmt .Sprintf ("%d-%d" , clustersHash , endpointsHash ), endpointsProto )
113+
114+ mostlySnap := * maybeMostlySnap
80115 mostlySnap .proxyKey = ucc .ResourceName ()
81116 mostlySnap .snap = & xds.EnvoySnapshot {
82117 Clusters : clusterResources ,
83- Endpoints : envoycache .NewResources (fmt .Sprintf ("%s-%d" , clustersVersion , endpointsHash ), endpointsProto ),
118+ Listeners : listenerResources ,
119+ Endpoints : endpointResources ,
84120 Routes : genericSnap .Routes ,
85- Listeners : genericSnap .Listeners ,
86121 }
122+
87123 l .Debug ("snapshotPerClient" , zap .String ("proxyKey" , mostlySnap .proxyKey ),
88124 zap .Stringer ("Listeners" , resourcesStringer (mostlySnap .snap .Listeners )),
89125 zap .Stringer ("Clusters" , resourcesStringer (mostlySnap .snap .Clusters )),
0 commit comments