Skip to content

Commit 0008d82

Browse files
committed
fix: detachHTTPRoutes uses Spec.ParentRefs not Status.Parents
Status.Parents is written by Envoy Gateway and can be stale or empty at finalization time. Spec.ParentRefs is written by NSO and is always authoritative. The old code checked Status.Parents to determine which HTTPRoutes referenced a gateway being finalized, then mutated Status.Parents via a status subresource update. This was wrong: if EG hadn't yet reconciled the route (e.g. during rapid gateway deletion or Karmada status aggregation lag), Status.Parents would be empty and the route would appear to have no parents, causing it to be deleted or left with stale status. In the converse case, EG could leave a stale Status.Parents entry after the spec parentRef was already removed, preventing cleanup. Now detachHTTPRoutes iterates Spec.ParentRefs, builds the remaining refs excluding the gateway being finalized, and either deletes the route (no remaining refs + deleteWhenNoParents) or updates Spec to remove the dead parentRef. EG will reconcile Status.Parents from the updated spec naturally. Fixes #231
1 parent cc2c309 commit 0008d82

1 file changed

Lines changed: 18 additions & 11 deletions

File tree

internal/controller/gateway_controller.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,26 +1596,33 @@ func (r *GatewayReconciler) detachHTTPRoutes(
15961596
continue
15971597
}
15981598

1599-
var parents []gatewayv1.RouteParentStatus
1600-
for _, parent := range route.Status.Parents {
1601-
if ptr.Deref(parent.ParentRef.Group, gatewayv1.GroupName) == gatewayv1.GroupName &&
1602-
ptr.Deref(parent.ParentRef.Kind, KindGateway) == KindGateway &&
1603-
string(parent.ParentRef.Name) == gateway.Name {
1604-
logger.Info("removing parent ref from httproute", jsonKeyName, route.Name, "parent", parent.ParentRef.Name)
1599+
var remainingRefs []gatewayv1.ParentReference
1600+
for _, ref := range route.Spec.ParentRefs {
1601+
if ptr.Deref(ref.Group, gatewayv1.GroupName) == gatewayv1.GroupName &&
1602+
ptr.Deref(ref.Kind, KindGateway) == KindGateway &&
1603+
string(ref.Name) == gateway.Name {
1604+
logger.Info("removing parent ref from httproute", jsonKeyName, route.Name, "parent", ref.Name)
16051605
continue
16061606
}
1607-
parents = append(parents, parent)
1607+
remainingRefs = append(remainingRefs, ref)
16081608
}
16091609

1610-
if len(parents) == 0 && deleteWhenNoParents {
1610+
if len(remainingRefs) == len(route.Spec.ParentRefs) {
1611+
continue
1612+
}
1613+
1614+
if len(remainingRefs) == 0 && deleteWhenNoParents {
16111615
logger.Info("deleting httproute due to no parents", jsonKeyName, route.Name)
16121616
if err := gatewayClient.Delete(ctx, &route); err != nil {
16131617
result.Err = err
16141618
return result
16151619
}
1616-
} else if !equality.Semantic.DeepEqual(route.Status.Parents, parents) {
1617-
route.Status.Parents = parents
1618-
result.AddStatusUpdate(gatewayClient, &route)
1620+
} else {
1621+
route.Spec.ParentRefs = remainingRefs
1622+
if err := gatewayClient.Update(ctx, &route); err != nil {
1623+
result.Err = err
1624+
return result
1625+
}
16191626
}
16201627
}
16211628
return result

0 commit comments

Comments
 (0)