package eventhandlers import ( "context" "fmt" "time" "github.com/golang/glog" "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/workqueue" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/reconcile" gateway_api "sigs.k8s.io/gateway-api/apis/v1beta1" "github.com/aws/aws-application-networking-k8s/pkg/config" ) type enqueueRequestsForGatewayEvent struct { client client.Client } func NewEnqueueRequestGatewayEvent(client client.Client) handler.EventHandler { return &enqueueRequestsForGatewayEvent{ client: client, } } var ZeroTransitionTime = metav1.NewTime(time.Time{}) func (h *enqueueRequestsForGatewayEvent) Create(e event.CreateEvent, queue workqueue.RateLimitingInterface) { gwNew := e.Object.(*gateway_api.Gateway) glog.V(2).Infof("Gateway Create and Spec is %v", gwNew.Spec) // initialize transition time gwNew.Status.Conditions[0].LastTransitionTime = ZeroTransitionTime h.enqueueImpactedHTTPRoute(queue, gwNew) } func (h *enqueueRequestsForGatewayEvent) Update(e event.UpdateEvent, queue workqueue.RateLimitingInterface) { glog.V(6).Info("Gateway Update ") gwOld := e.ObjectOld.(*gateway_api.Gateway) gwNew := e.ObjectNew.(*gateway_api.Gateway) if !equality.Semantic.DeepEqual(gwOld.Spec, gwNew.Spec) { glog.V(2).Infof("Gateway Update old spec %v to new spec %v", gwOld.Spec, gwNew.Spec) // initialize transition time gwNew.Status.Conditions[0].LastTransitionTime = ZeroTransitionTime h.enqueueImpactedHTTPRoute(queue, gwNew) } } func (h *enqueueRequestsForGatewayEvent) Delete(e event.DeleteEvent, queue workqueue.RateLimitingInterface) { fmt.Printf("TODO Gatway Delete") } func (h *enqueueRequestsForGatewayEvent) Generic(e event.GenericEvent, queue workqueue.RateLimitingInterface) { } func (h *enqueueRequestsForGatewayEvent) enqueueImpactedHTTPRoute(queue workqueue.RateLimitingInterface, gw *gateway_api.Gateway) { httpRouteList := &gateway_api.HTTPRouteList{} h.client.List(context.TODO(), httpRouteList) for _, httpRoute := range httpRouteList.Items { if len(httpRoute.Spec.ParentRefs) <= 0 { glog.V(6).Infof("Ignore httpRoute no parentRefs %s", httpRoute.Name) continue } // find the parent gw object var gwNamespace = httpRoute.Namespace if httpRoute.Spec.ParentRefs[0].Namespace != nil { gwNamespace = string(*httpRoute.Spec.ParentRefs[0].Namespace) } gwName := types.NamespacedName{ Namespace: gwNamespace, Name: string(httpRoute.Spec.ParentRefs[0].Name), } gw := &gateway_api.Gateway{} if err := h.client.Get(context.TODO(), gwName, gw); err != nil { glog.V(6).Infof("Ignore HTTPRoute with unknown parentRef %s\n", httpRoute.Name) continue } // find the parent gateway class name gwClass := &gateway_api.GatewayClass{} gwClassName := types.NamespacedName{ Namespace: "default", Name: string(gw.Spec.GatewayClassName), } if err := h.client.Get(context.TODO(), gwClassName, gwClass); err != nil { glog.V(6).Infof("Ignore HTTPRoute with unknown Gateway %s \n", httpRoute.Name) continue } if gwClass.Spec.ControllerName == config.LatticeGatewayControllerName { glog.V(2).Infof("Trigger HTTPRoute from Gateway event , httpRoute %s", httpRoute.Name) queue.Add(reconcile.Request{ NamespacedName: types.NamespacedName{ Namespace: httpRoute.Namespace, Name: httpRoute.Name, }, }) } } }