Skip to content

Commit 53a0370

Browse files
author
Doyoon Kim
authored
Fix condition handling of gateways and routes (#287)
* Refactor condition handling of gateways and routes
1 parent 6d52485 commit 53a0370

File tree

3 files changed

+98
-120
lines changed

3 files changed

+98
-120
lines changed

controllers/conditions.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package controllers
2+
3+
import (
4+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
5+
)
6+
7+
func updateCondition(conditions []metav1.Condition, newCond metav1.Condition) []metav1.Condition {
8+
newConditions := make([]metav1.Condition, 0)
9+
10+
found := false
11+
for _, cond := range conditions {
12+
if cond.Type == newCond.Type {
13+
// Update existing condition. Time is kept only if status is unchanged.
14+
newCond.LastTransitionTime = cond.LastTransitionTime
15+
if cond.Status != newCond.Status {
16+
newCond.LastTransitionTime = metav1.Now()
17+
}
18+
newConditions = append(newConditions, newCond)
19+
found = true
20+
} else {
21+
newConditions = append(newConditions, cond)
22+
}
23+
}
24+
25+
if !found {
26+
// Add new condition instead.
27+
newCond.LastTransitionTime = metav1.Now()
28+
newConditions = append(newConditions, newCond)
29+
}
30+
31+
return newConditions
32+
}

controllers/gateway_controller.go

Lines changed: 41 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ package controllers
1919
import (
2020
"context"
2121
"fmt"
22-
"time"
23-
2422
"github.com/golang/glog"
2523
"github.com/pkg/errors"
2624

@@ -258,21 +256,15 @@ func (r *GatewayReconciler) cleanupGatewayResources(ctx context.Context, gw *gat
258256

259257
func (r *GatewayReconciler) updateGatewayStatus(ctx context.Context, serviceNetworkStatus *latticestore.ServiceNetwork, gw *gateway_api.Gateway) error {
260258

261-
glog.V(6).Infof("updateGatewayStatus: updating last transition time \n")
262259
gwOld := gw.DeepCopy()
263260

264-
if len(gw.Status.Conditions) <= 1 {
265-
condition := metav1.Condition{}
266-
gw.Status.Conditions = append(gw.Status.Conditions, condition)
267-
}
268-
269-
gw.Status.Conditions[1].LastTransitionTime = metav1.NewTime(time.Now())
270-
gw.Status.Conditions[1].Status = "True"
271-
gw.Status.Conditions[1].Message = fmt.Sprintf("aws-gateway-arn: %s", serviceNetworkStatus.ARN)
272-
gw.Status.Conditions[1].Reason = "Reconciled"
273-
gw.Status.Conditions[1].ObservedGeneration = gw.Generation
274-
gw.Status.Conditions[0].ObservedGeneration = gw.Generation // update the accept
275-
gw.Status.Conditions[1].Type = string(gateway_api.GatewayConditionProgrammed)
261+
gw.Status.Conditions = updateCondition(gw.Status.Conditions, metav1.Condition{
262+
Type: string(gateway_api.GatewayConditionProgrammed),
263+
Status: metav1.ConditionTrue,
264+
ObservedGeneration: gw.Generation,
265+
Reason: string(gateway_api.GatewayReasonProgrammed),
266+
Message: fmt.Sprintf("aws-gateway-arn: %s", serviceNetworkStatus.ARN),
267+
})
276268

277269
// TODO following is causing crash on some platform, see https://t.corp.amazon.com/b7c9ea6c-5168-4616-b718-c1bdf78dbdf1/communication
278270
//gw.Annotations["gateway.networking.k8s.io/aws-gateway-id"] = serviceNetworkStatus.ID
@@ -289,20 +281,25 @@ func (r *GatewayReconciler) updateGatewayAcceptStatus(ctx context.Context, gw *g
289281

290282
gwOld := gw.DeepCopy()
291283

292-
glog.V(6).Infof("updateGatewayStatus: updating last transition time \n")
293-
if gw.Status.Conditions[0].LastTransitionTime == eventhandlers.ZeroTransitionTime {
294-
gw.Status.Conditions[0].LastTransitionTime = metav1.NewTime(time.Now())
295-
}
284+
var cond metav1.Condition
296285
if accepted {
297-
gw.Status.Conditions[0].Status = "True"
298-
gw.Status.Conditions[0].Reason = "Accepted"
286+
cond = metav1.Condition{
287+
Type: string(gateway_api.GatewayConditionAccepted),
288+
ObservedGeneration: gw.Generation,
289+
Message: config.LatticeGatewayControllerName,
290+
Status: metav1.ConditionTrue,
291+
Reason: string(gateway_api.GatewayReasonAccepted),
292+
}
299293
} else {
300-
gw.Status.Conditions[0].Status = "False"
301-
gw.Status.Conditions[0].Reason = "Invalid"
294+
cond = metav1.Condition{
295+
Type: string(gateway_api.GatewayConditionAccepted),
296+
ObservedGeneration: gw.Generation,
297+
Message: config.LatticeGatewayControllerName,
298+
Status: metav1.ConditionFalse,
299+
Reason: string(gateway_api.GatewayReasonInvalid),
300+
}
302301
}
303-
gw.Status.Conditions[0].Message = config.LatticeGatewayControllerName
304-
gw.Status.Conditions[0].ObservedGeneration = gw.Generation
305-
gw.Status.Conditions[0].Type = string(gateway_api.GatewayConditionAccepted)
302+
gw.Status.Conditions = updateCondition(gw.Status.Conditions, cond)
306303

307304
if err := r.Client.Status().Patch(ctx, gw, client.MergeFrom(gwOld)); err != nil {
308305
glog.V(2).Infof("Failed to Patch acceptance status, err %v gw %v", err, gw)
@@ -312,27 +309,6 @@ func (r *GatewayReconciler) updateGatewayAcceptStatus(ctx context.Context, gw *g
312309
return nil
313310
}
314311

315-
func (r *GatewayReconciler) updateBadStatus(ctx context.Context, message string, gw *gateway_api.Gateway) error {
316-
317-
gwOld := gw.DeepCopy()
318-
319-
glog.V(6).Infof("updateGatewayStatus: updating last transition time \n")
320-
if gw.Status.Conditions[0].LastTransitionTime == eventhandlers.ZeroTransitionTime {
321-
gw.Status.Conditions[0].LastTransitionTime = metav1.NewTime(time.Now())
322-
}
323-
324-
gw.Status.Conditions[0].Status = "False"
325-
gw.Status.Conditions[0].Message = message
326-
gw.Status.Conditions[0].Reason = "NoReconcile"
327-
gw.Status.Conditions[0].Type = "NotAccepted"
328-
329-
if err := r.Client.Status().Patch(ctx, gw, client.MergeFrom(gwOld)); err != nil {
330-
return errors.Wrapf(err, "failed to update gateway status")
331-
}
332-
333-
return nil
334-
}
335-
336312
func UpdateHTTPRouteListenerStatus(ctx context.Context, k8sclient client.Client, httproute *gateway_api.HTTPRoute) error {
337313
gw := &gateway_api.Gateway{}
338314

@@ -391,8 +367,6 @@ func UpdateGWListenerStatus(ctx context.Context, k8sclient client.Client, gw *ga
391367

392368
glog.V(6).Infof("Before update, the snapshot of listeners %v \n", gw.Status.Listeners)
393369

394-
gw.Status.Listeners = make([]gateway_api.ListenerStatus, 0)
395-
396370
httpRouteList := &gateway_api.HTTPRouteList{}
397371

398372
k8sclient.List(context.TODO(), httpRouteList)
@@ -441,7 +415,7 @@ func UpdateGWListenerStatus(ctx context.Context, k8sclient client.Client, gw *ga
441415
Status: metav1.ConditionFalse,
442416
Reason: string(gateway_api.ListenerReasonInvalidRouteKinds),
443417
ObservedGeneration: gw.Generation,
444-
LastTransitionTime: metav1.NewTime(time.Now()),
418+
LastTransitionTime: metav1.Now(),
445419
}
446420
listenerStatus.SupportedKinds = supportedkind
447421
listenerStatus.Conditions = append(listenerStatus.Conditions, condition)
@@ -451,12 +425,11 @@ func UpdateGWListenerStatus(ctx context.Context, k8sclient client.Client, gw *ga
451425
hasValidListener = true
452426

453427
condition := metav1.Condition{
454-
Type: "Accepted",
455-
Status: "True",
456-
Reason: "Accepted",
428+
Type: string(gateway_api.ListenerConditionAccepted),
429+
Status: metav1.ConditionTrue,
430+
Reason: string(gateway_api.ListenerReasonAccepted),
457431
ObservedGeneration: gw.Generation,
458-
// TODO need to use previous one
459-
LastTransitionTime: metav1.NewTime(time.Now()),
432+
LastTransitionTime: metav1.Now(),
460433
}
461434

462435
for _, httpRoute := range httpRouteList.Items {
@@ -499,8 +472,20 @@ func UpdateGWListenerStatus(ctx context.Context, k8sclient client.Client, gw *ga
499472
listenerStatus.Conditions = append(listenerStatus.Conditions, condition)
500473

501474
}
502-
gw.Status.Listeners = append(gw.Status.Listeners, listenerStatus)
503475

476+
found := false
477+
for i, oldStatus := range gw.Status.Listeners {
478+
if oldStatus.Name == listenerStatus.Name {
479+
gw.Status.Listeners[i].AttachedRoutes = listenerStatus.AttachedRoutes
480+
gw.Status.Listeners[i].SupportedKinds = listenerStatus.SupportedKinds
481+
// Only have one condition in the logic
482+
gw.Status.Listeners[i].Conditions = updateCondition(gw.Status.Listeners[i].Conditions, listenerStatus.Conditions[0])
483+
found = true
484+
}
485+
}
486+
if !found {
487+
gw.Status.Listeners = append(gw.Status.Listeners, listenerStatus)
488+
}
504489
}
505490

506491
glog.V(6).Infof("After update, the snapshot of listener status %v", gw.Status.Listeners)

controllers/httproute_controller.go

Lines changed: 25 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ package controllers
1919
import (
2020
"context"
2121
"fmt"
22-
"time"
23-
2422
"github.com/golang/glog"
2523
"github.com/pkg/errors"
2624

@@ -276,11 +274,9 @@ func (r *HTTPRouteReconciler) reconcileHTTPRouteResource(ctx context.Context, ht
276274
func (r *HTTPRouteReconciler) updateHTTPRouteStatus(ctx context.Context, dns string, httproute *gateway_api.HTTPRoute) error {
277275
glog.V(6).Infof("updateHTTPRouteStatus: httproute %v, dns %v\n", httproute, dns)
278276
httprouteOld := httproute.DeepCopy()
279-
compare := true
280277

281278
if len(httproute.ObjectMeta.Annotations) == 0 {
282279
httproute.ObjectMeta.Annotations = make(map[string]string)
283-
compare = false
284280
}
285281

286282
httproute.ObjectMeta.Annotations[LatticeAssignedDomainName] = dns
@@ -292,46 +288,34 @@ func (r *HTTPRouteReconciler) updateHTTPRouteStatus(ctx context.Context, dns str
292288

293289
if len(httproute.Status.RouteStatus.Parents) == 0 {
294290
httproute.Status.RouteStatus.Parents = make([]gateway_api.RouteParentStatus, 1)
295-
compare = false
296291
}
297-
298292
httproute.Status.RouteStatus.Parents[0].ParentRef = httproute.Spec.ParentRefs[0]
299293
httproute.Status.RouteStatus.Parents[0].ControllerName = config.LatticeGatewayControllerName
300294

301-
timeNow := metav1.NewTime(time.Now())
302-
if httprouteOld.Status.RouteStatus.Parents != nil {
303-
if len(httprouteOld.Status.RouteStatus.Parents[0].Conditions) > 0 {
304-
timeNow = httprouteOld.Status.Parents[0].Conditions[0].LastTransitionTime
305-
}
306-
}
307-
308-
accepted := metav1.Condition{
309-
Type: string(gateway_api.RouteConditionAccepted),
310-
Status: metav1.ConditionTrue,
311-
ObservedGeneration: httproute.Generation,
312-
LastTransitionTime: timeNow,
313-
Reason: string(gateway_api.RouteReasonAccepted),
314-
Message: fmt.Sprintf("DNS Name: %s", dns),
315-
}
316-
resolvedRefs := metav1.Condition{
317-
Type: string(gateway_api.RouteConditionResolvedRefs),
318-
Status: metav1.ConditionTrue,
319-
ObservedGeneration: httproute.Generation,
320-
LastTransitionTime: timeNow,
321-
Reason: string(gateway_api.RouteReasonResolvedRefs),
322-
Message: fmt.Sprintf("DNS Name: %s", dns),
323-
}
324-
httproute.Status.RouteStatus.Parents[0].Conditions = []metav1.Condition{
325-
accepted,
326-
resolvedRefs,
327-
}
328-
329295
// Update listener Status
330-
UpdateHTTPRouteListenerStatus(ctx, r.Client, httproute)
331-
332-
if compare && r.compareHttproutes(httproute, httprouteOld) {
333-
glog.V(6).Infof("updateHTTPRouteStatus: httproute is already up-to-date %v, dns %v\n", httproute, dns)
334-
return nil
296+
if err := UpdateHTTPRouteListenerStatus(ctx, r.Client, httproute); err != nil {
297+
updateRouteCondition(httproute, metav1.Condition{
298+
Type: string(gateway_api.RouteConditionAccepted),
299+
Status: metav1.ConditionFalse,
300+
ObservedGeneration: httproute.Generation,
301+
Reason: string(gateway_api.RouteReasonNoMatchingParent),
302+
Message: fmt.Sprintf("Could not match gateway %s: %s", httproute.Spec.ParentRefs[0].Name, err.Error()),
303+
})
304+
} else {
305+
updateRouteCondition(httproute, metav1.Condition{
306+
Type: string(gateway_api.RouteConditionAccepted),
307+
Status: metav1.ConditionTrue,
308+
ObservedGeneration: httproute.Generation,
309+
Reason: string(gateway_api.RouteReasonAccepted),
310+
Message: fmt.Sprintf("DNS Name: %s", dns),
311+
})
312+
updateRouteCondition(httproute, metav1.Condition{
313+
Type: string(gateway_api.RouteConditionResolvedRefs),
314+
Status: metav1.ConditionTrue,
315+
ObservedGeneration: httproute.Generation,
316+
Reason: string(gateway_api.RouteReasonResolvedRefs),
317+
Message: fmt.Sprintf("DNS Name: %s", dns),
318+
})
335319
}
336320

337321
if err := r.Client.Status().Patch(ctx, httproute, client.MergeFrom(httprouteOld)); err != nil {
@@ -343,31 +327,8 @@ func (r *HTTPRouteReconciler) updateHTTPRouteStatus(ctx context.Context, dns str
343327
return nil
344328
}
345329

346-
func (r *HTTPRouteReconciler) compareHttproutes(httproute1 *gateway_api.HTTPRoute, httproute2 *gateway_api.HTTPRoute) bool {
347-
348-
result := false
349-
350-
if httproute1 == httproute2 {
351-
return true
352-
}
353-
354-
if (httproute1.Name == httproute2.Name) && (httproute1.Namespace == httproute2.Namespace) &&
355-
(len(httproute1.Status.RouteStatus.Parents[0].Conditions) == len(httproute2.Status.RouteStatus.Parents[0].Conditions)) &&
356-
(httproute1.Status.RouteStatus.Parents[0].ParentRef.Name == httproute2.Status.RouteStatus.Parents[0].ParentRef.Name) &&
357-
(httproute1.Status.RouteStatus.Parents[0].ControllerName == httproute2.Status.RouteStatus.Parents[0].ControllerName) &&
358-
(httproute1.ObjectMeta.Annotations[LatticeAssignedDomainName] == httproute2.ObjectMeta.Annotations[LatticeAssignedDomainName]) {
359-
i := 0
360-
for _, condition := range httproute1.Status.RouteStatus.Parents[0].Conditions {
361-
if condition != httproute2.Status.RouteStatus.Parents[0].Conditions[i] {
362-
result = false
363-
break
364-
}
365-
i++
366-
}
367-
result = true
368-
}
369-
370-
return result
330+
func updateRouteCondition(httproute *gateway_api.HTTPRoute, updated metav1.Condition) {
331+
httproute.Status.RouteStatus.Parents[0].Conditions = updateCondition(httproute.Status.RouteStatus.Parents[0].Conditions, updated)
371332
}
372333

373334
// SetupWithManager sets up the controller with the Manager.

0 commit comments

Comments
 (0)