Skip to content

Commit 1a7125b

Browse files
authored
Merge branch 'main' into dym-lb-policy
2 parents ca76bd8 + 3f70a89 commit 1a7125b

14 files changed

Lines changed: 227 additions & 60 deletions

internal/gatewayapi/backend.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ import (
2020
)
2121

2222
func (t *Translator) ProcessBackends(backends []*egv1a1.Backend, backendTLSPolicies []*gwapiv1.BackendTLSPolicy) []*egv1a1.Backend {
23+
backendCopies := backendCopiesWithStatusDeepCopy(backends)
2324
res := make([]*egv1a1.Backend, 0, len(backends))
24-
for _, backend := range backends {
25+
for i := range backends {
26+
backend := backendCopies[i]
2527
// Ensure Backends are enabled
2628
if !t.BackendEnabled {
2729
status.UpdateBackendStatusAcceptedCondition(backend, false,
@@ -203,3 +205,15 @@ func validateIP(epIP *egv1a1.IPEndpoint, runningOnHost bool) status.Error {
203205
}
204206
return nil
205207
}
208+
209+
// backendCopiesWithStatusDeepCopy returns shallow copies with deep-copied Status fields.
210+
// Status is mutated during translation and shares a pointer with the watchable coalesce goroutine.
211+
func backendCopiesWithStatusDeepCopy(backends []*egv1a1.Backend) []*egv1a1.Backend {
212+
copies := make([]*egv1a1.Backend, len(backends))
213+
for i, b := range backends {
214+
out := *b
215+
b.Status.DeepCopyInto(&out.Status)
216+
copies[i] = &out
217+
}
218+
return copies
219+
}

internal/gatewayapi/backendtrafficpolicy.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ func (t *Translator) ProcessBackendTrafficPolicies(
248248
SectionIndex: make(map[types.NamespacedName]sets.Set[string], gatewayMapSize),
249249
}
250250

251+
policyCopies := backendTrafficPolicyCopiesWithStatusDeepCopy(backendTrafficPolicies)
252+
251253
handledPolicies := make(map[types.NamespacedName]*egv1a1.BackendTrafficPolicy, policyMapSize)
252254

253255
// Translate
@@ -260,15 +262,15 @@ func (t *Translator) ProcessBackendTrafficPolicies(
260262
t.buildGatewayPolicyMap(backendTrafficPolicies, gateways, gatewayMap, gatewayPolicyMap)
261263

262264
// Process the policies targeting RouteRules
263-
for _, currPolicy := range backendTrafficPolicies {
265+
for i, currPolicy := range backendTrafficPolicies {
264266
policyName := utils.NamespacedName(currPolicy)
265267
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes, currPolicy.Namespace)
266268
for _, currTarget := range targetRefs {
267269
// If the target is not a gateway, then it's an xRoute. If the section name is defined, then it's a route rule.
268270
if currTarget.Kind != resource.KindGateway && currTarget.SectionName != nil {
269271
policy, found := handledPolicies[policyName]
270272
if !found {
271-
policy = currPolicy
273+
policy = policyCopies[i]
272274
handledPolicies[policyName] = policy
273275
res = append(res, policy)
274276
}
@@ -280,15 +282,15 @@ func (t *Translator) ProcessBackendTrafficPolicies(
280282
}
281283

282284
// Process the policies targeting Routes
283-
for _, currPolicy := range backendTrafficPolicies {
285+
for i, currPolicy := range backendTrafficPolicies {
284286
policyName := utils.NamespacedName(currPolicy)
285287
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes, currPolicy.Namespace)
286288
for _, currTarget := range targetRefs {
287289
// If the target is not a gateway, then it's an xRoute. If the section name is not defined, then it's a route.
288290
if currTarget.Kind != resource.KindGateway && currTarget.SectionName == nil {
289291
policy, found := handledPolicies[policyName]
290292
if !found {
291-
policy = currPolicy
293+
policy = policyCopies[i]
292294
handledPolicies[policyName] = policy
293295
res = append(res, policy)
294296
}
@@ -300,15 +302,15 @@ func (t *Translator) ProcessBackendTrafficPolicies(
300302
}
301303

302304
// Process the policies targeting Listeners
303-
for _, currPolicy := range backendTrafficPolicies {
305+
for i, currPolicy := range backendTrafficPolicies {
304306
policyName := utils.NamespacedName(currPolicy)
305307
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways, currPolicy.Namespace)
306308
for _, currTarget := range targetRefs {
307309
// If the target is a gateway and the section name is defined, then it's a listener.
308310
if currTarget.Kind == resource.KindGateway && currTarget.SectionName != nil {
309311
policy, found := handledPolicies[policyName]
310312
if !found {
311-
policy = currPolicy
313+
policy = policyCopies[i]
312314
handledPolicies[policyName] = policy
313315
res = append(res, policy)
314316
}
@@ -319,15 +321,15 @@ func (t *Translator) ProcessBackendTrafficPolicies(
319321
}
320322

321323
// Process the policies targeting Gateways
322-
for _, currPolicy := range backendTrafficPolicies {
324+
for i, currPolicy := range backendTrafficPolicies {
323325
policyName := utils.NamespacedName(currPolicy)
324326
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways, currPolicy.Namespace)
325327
for _, currTarget := range targetRefs {
326328
// If the target is a gateway and the section name is not defined, then it's a gateway.
327329
if currTarget.Kind == resource.KindGateway && currTarget.SectionName == nil {
328330
policy, found := handledPolicies[policyName]
329331
if !found {
330-
policy = currPolicy
332+
policy = policyCopies[i]
331333
handledPolicies[policyName] = policy
332334
res = append(res, policy)
333335
}
@@ -2077,3 +2079,15 @@ func buildRouteStatName(routeStatName string, metadata *ir.ResourceMetadata) *st
20772079

20782080
return &statName
20792081
}
2082+
2083+
// backendTrafficPolicyCopiesWithStatusDeepCopy returns shallow copies with deep-copied Status fields.
2084+
// Status is mutated during translation and shares a pointer with the watchable coalesce goroutine.
2085+
func backendTrafficPolicyCopiesWithStatusDeepCopy(policies []*egv1a1.BackendTrafficPolicy) []*egv1a1.BackendTrafficPolicy {
2086+
copies := make([]*egv1a1.BackendTrafficPolicy, len(policies))
2087+
for i, p := range policies {
2088+
out := *p
2089+
p.Status.DeepCopyInto(&out.Status)
2090+
copies[i] = &out
2091+
}
2092+
return copies
2093+
}

internal/gatewayapi/clienttrafficpolicy.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,15 @@ func (t *Translator) ProcessClientTrafficPolicies(
7777
gatewayMap[key] = &policyGatewayTargetContext{GatewayContext: gw}
7878
}
7979

80+
policyCopies := clientTrafficPolicyCopiesWithStatusDeepCopy(clientTrafficPolicies)
81+
8082
handledPolicies := make(map[types.NamespacedName]*egv1a1.ClientTrafficPolicy)
8183
// Translate
8284
// 1. First translate Policies with a sectionName set
8385
// 2. Then loop again and translate the policies without a sectionName
8486
// TODO: Import sort order to ensure policy with same section always appear
8587
// before policy with no section so below loops can be flattened into 1.
86-
for _, currPolicy := range clientTrafficPolicies {
88+
for i, currPolicy := range clientTrafficPolicies {
8789
policyName := utils.NamespacedName(currPolicy)
8890
// This loop only handles policies that target a specific section. When
8991
// targeting a policy with a selector, it's not possible to specify a SectionName
@@ -93,7 +95,7 @@ func (t *Translator) ProcessClientTrafficPolicies(
9395
if hasSectionName(&currTarget) {
9496
policy, found := handledPolicies[policyName]
9597
if !found {
96-
policy = currPolicy
98+
policy = policyCopies[i]
9799
handledPolicies[policyName] = policy
98100
res = append(res, policy)
99101
}
@@ -193,15 +195,15 @@ func (t *Translator) ProcessClientTrafficPolicies(
193195
}
194196

195197
// Policy with no section set (targeting all sections)
196-
for _, currPolicy := range clientTrafficPolicies {
198+
for i, currPolicy := range clientTrafficPolicies {
197199
policyName := utils.NamespacedName(currPolicy)
198200
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways, currPolicy.Namespace)
199201
for _, currTarget := range targetRefs {
200202
if !hasSectionName(&currTarget) {
201203

202204
policy, found := handledPolicies[policyName]
203205
if !found {
204-
policy = currPolicy
206+
policy = policyCopies[i]
205207
res = append(res, policy)
206208
handledPolicies[policyName] = policy
207209
}
@@ -1339,3 +1341,15 @@ func translateHeaderModifier(headerModifier *egv1a1.HTTPHeaderFilter, modType st
13391341

13401342
return addRequestHeaders, removeRequestHeaders, removeRequestHeadersOnMatch, errs
13411343
}
1344+
1345+
// clientTrafficPolicyCopiesWithStatusDeepCopy returns shallow copies with deep-copied Status fields.
1346+
// Status is mutated during translation and shares a pointer with the watchable coalesce goroutine.
1347+
func clientTrafficPolicyCopiesWithStatusDeepCopy(policies []*egv1a1.ClientTrafficPolicy) []*egv1a1.ClientTrafficPolicy {
1348+
copies := make([]*egv1a1.ClientTrafficPolicy, len(policies))
1349+
for i, p := range policies {
1350+
out := *p
1351+
p.Status.DeepCopyInto(&out.Status)
1352+
copies[i] = &out
1353+
}
1354+
return copies
1355+
}

internal/gatewayapi/envoyextensionpolicy.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(
103103
// The routes are grouped by sectionNames of their targetRefs.
104104
gatewayRouteMap := make(map[string]map[string]sets.Set[string])
105105

106+
policyCopies := envoyExtensionPolicyCopiesWithStatusDeepCopy(envoyExtensionPolicies)
107+
106108
handledPolicies := make(map[types.NamespacedName]*egv1a1.EnvoyExtensionPolicy)
107109

108110
// Translate
@@ -112,15 +114,15 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(
112114
// 4. Finally, the policies targeting Gateways
113115

114116
// Process the policies targeting RouteRules
115-
for _, currPolicy := range envoyExtensionPolicies {
117+
for i, currPolicy := range envoyExtensionPolicies {
116118
policyName := utils.NamespacedName(currPolicy)
117119
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes, currPolicy.Namespace)
118120
for _, currTarget := range targetRefs {
119121
// If the target is not a gateway, then it's an xRoute. If the section name is defined, then it's a route rule.
120122
if currTarget.Kind != resource.KindGateway && currTarget.SectionName != nil {
121123
policy, found := handledPolicies[policyName]
122124
if !found {
123-
policy = currPolicy
125+
policy = policyCopies[i]
124126
res = append(res, policy)
125127
handledPolicies[policyName] = policy
126128
}
@@ -132,15 +134,15 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(
132134
}
133135

134136
// Process the policies targeting xRoutes
135-
for _, currPolicy := range envoyExtensionPolicies {
137+
for i, currPolicy := range envoyExtensionPolicies {
136138
policyName := utils.NamespacedName(currPolicy)
137139
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes, currPolicy.Namespace)
138140
for _, currTarget := range targetRefs {
139141
// If the target is not a gateway, then it's an xRoute. If the section name is not defined, then it's a route.
140142
if currTarget.Kind != resource.KindGateway && currTarget.SectionName == nil {
141143
policy, found := handledPolicies[policyName]
142144
if !found {
143-
policy = currPolicy
145+
policy = policyCopies[i]
144146
res = append(res, policy)
145147
handledPolicies[policyName] = policy
146148
}
@@ -152,15 +154,15 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(
152154
}
153155

154156
// Process the policies targeting Listeners
155-
for _, currPolicy := range envoyExtensionPolicies {
157+
for i, currPolicy := range envoyExtensionPolicies {
156158
policyName := utils.NamespacedName(currPolicy)
157159
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways, currPolicy.Namespace)
158160
for _, currTarget := range targetRefs {
159161
// If the target is a gateway and the section name is defined, then it's a listener.
160162
if currTarget.Kind == resource.KindGateway && currTarget.SectionName != nil {
161163
policy, found := handledPolicies[policyName]
162164
if !found {
163-
policy = currPolicy
165+
policy = policyCopies[i]
164166
res = append(res, policy)
165167
handledPolicies[policyName] = policy
166168
}
@@ -172,15 +174,15 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(
172174
}
173175

174176
// Process the policies targeting Gateways
175-
for _, currPolicy := range envoyExtensionPolicies {
177+
for i, currPolicy := range envoyExtensionPolicies {
176178
policyName := utils.NamespacedName(currPolicy)
177179
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways, currPolicy.Namespace)
178180
for _, currTarget := range targetRefs {
179181
// If the target is a gateway and the section name is not defined, then it's a gateway.
180182
if currTarget.Kind == resource.KindGateway && currTarget.SectionName == nil {
181183
policy, found := handledPolicies[policyName]
182184
if !found {
183-
policy = currPolicy
185+
policy = policyCopies[i]
184186
res = append(res, policy)
185187
handledPolicies[policyName] = policy
186188
}
@@ -1222,3 +1224,15 @@ func (t *Translator) buildDynamicModules(
12221224

12231225
return dmIRList, errs
12241226
}
1227+
1228+
// envoyExtensionPolicyCopiesWithStatusDeepCopy returns shallow copies with deep-copied Status fields.
1229+
// Status is mutated during translation and shares a pointer with the watchable coalesce goroutine.
1230+
func envoyExtensionPolicyCopiesWithStatusDeepCopy(policies []*egv1a1.EnvoyExtensionPolicy) []*egv1a1.EnvoyExtensionPolicy {
1231+
copies := make([]*egv1a1.EnvoyExtensionPolicy, len(policies))
1232+
for i, p := range policies {
1233+
out := *p
1234+
p.Status.DeepCopyInto(&out.Status)
1235+
copies[i] = &out
1236+
}
1237+
return copies
1238+
}

internal/gatewayapi/envoypatchpolicy.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ import (
1717
"github.com/envoyproxy/gateway/internal/ir"
1818
)
1919

20-
func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.EnvoyPatchPolicy, xdsIR resource.XdsIRMap) {
20+
func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.EnvoyPatchPolicy, xdsIR resource.XdsIRMap) []*egv1a1.EnvoyPatchPolicy {
2121
// EnvoyPatchPolicies are already sorted by the provider layer (priority, then timestamp, then name)
22+
policyCopies := envoyPatchPolicyCopiesWithStatusDeepCopy(envoyPatchPolicies)
23+
res := make([]*egv1a1.EnvoyPatchPolicy, 0, len(envoyPatchPolicies))
2224

23-
for _, policy := range envoyPatchPolicies {
25+
for i := range envoyPatchPolicies {
26+
policy := policyCopies[i]
27+
res = append(res, policy)
2428
var (
2529
ancestorRef gwapiv1.ParentReference
2630
resolveErr *status.PolicyResolveError
@@ -139,4 +143,18 @@ func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.Envo
139143
// Set Accepted=True
140144
status.SetAcceptedForPolicyAncestor(&policy.Status, &ancestorRef, t.GatewayControllerName, policy.Generation)
141145
}
146+
147+
return res
148+
}
149+
150+
// envoyPatchPolicyCopiesWithStatusDeepCopy returns shallow copies with deep-copied Status fields.
151+
// Status is mutated during translation and shares a pointer with the watchable coalesce goroutine.
152+
func envoyPatchPolicyCopiesWithStatusDeepCopy(policies []*egv1a1.EnvoyPatchPolicy) []*egv1a1.EnvoyPatchPolicy {
153+
copies := make([]*egv1a1.EnvoyPatchPolicy, len(policies))
154+
for i, p := range policies {
155+
out := *p
156+
p.Status.DeepCopyInto(&out.Status)
157+
copies[i] = &out
158+
}
159+
return copies
142160
}

0 commit comments

Comments
 (0)