in pkg/controllers/gateway_controller.go [293:431]
func UpdateGWListenerStatus(ctx context.Context, k8sClient client.Client, gw *gwv1.Gateway) error {
hasValidListener := false
gwOld := gw.DeepCopy()
routes, err := core.ListAllRoutes(ctx, k8sClient)
if err != nil {
return err
}
// Add one of lattice domains as GW address. This is supposed to be a single ingress endpoint (or a single pool of them)
// but we have different endpoints for each service. This can represent incorrect value in some cases (e.g. cross-account)
// Due to size limit, we cannot put all service addresses here.
if len(routes) > 0 {
gw.Status.Addresses = []gwv1.GatewayStatusAddress{}
addressType := gwv1.HostnameAddressType
for _, route := range routes {
if route.DeletionTimestamp().IsZero() && len(route.K8sObject().GetAnnotations()) > 0 {
if domain, exists := route.K8sObject().GetAnnotations()[LatticeAssignedDomainName]; exists {
gw.Status.Addresses = append(gw.Status.Addresses, gwv1.GatewayStatusAddress{
Type: &addressType,
Value: domain,
})
break
}
}
}
}
if len(gw.Spec.Listeners) == 0 {
return fmt.Errorf("failed to find gateway listener")
}
defaultListener := gw.Spec.Listeners[0]
// go through each section of gw
for _, listener := range gw.Spec.Listeners {
listenerStatus := gwv1.ListenerStatus{
Name: listener.Name,
}
// mark listenerStatus's condition
listenerStatus.Conditions = make([]metav1.Condition, 0)
//Check if RouteGroupKind in listener spec is supported
validListener, supportedKinds := listenerRouteGroupKindSupported(listener)
if !validListener {
condition := metav1.Condition{
Type: string(gwv1.ListenerConditionResolvedRefs),
Status: metav1.ConditionFalse,
Reason: string(gwv1.ListenerReasonInvalidRouteKinds),
ObservedGeneration: gw.Generation,
LastTransitionTime: metav1.Now(),
}
listenerStatus.SupportedKinds = supportedKinds
listenerStatus.Conditions = append(listenerStatus.Conditions, condition)
} else {
hasValidListener = true
condition := metav1.Condition{
Type: string(gwv1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: string(gwv1.ListenerReasonAccepted),
ObservedGeneration: gw.Generation,
LastTransitionTime: metav1.Now(),
}
for _, route := range routes {
if !route.DeletionTimestamp().IsZero() {
// Ignore the deleted route
continue
}
for _, parentRef := range route.Spec().ParentRefs() {
if parentRef.Name != gwv1.ObjectName(gw.Name) {
continue
}
if parentRef.Namespace != nil &&
*parentRef.Namespace != gwv1.Namespace(gw.Namespace) {
continue
}
var sectionName string
if parentRef.SectionName == nil {
sectionName = string(defaultListener.Name)
} else {
sectionName = string(*parentRef.SectionName)
}
if sectionName != string(listener.Name) {
continue
}
if parentRef.Port != nil && *parentRef.Port != listener.Port {
continue
}
listenerStatus.AttachedRoutes++
}
}
if listener.Protocol == gwv1.HTTPSProtocolType {
listenerStatus.SupportedKinds = append(listenerStatus.SupportedKinds, gwv1.RouteGroupKind{
Kind: "GRPCRoute",
})
}
listenerStatus.SupportedKinds = append(listenerStatus.SupportedKinds, gwv1.RouteGroupKind{
Kind: "HTTPRoute",
})
listenerStatus.Conditions = append(listenerStatus.Conditions, condition)
}
found := false
for i, oldStatus := range gw.Status.Listeners {
if oldStatus.Name == listenerStatus.Name {
gw.Status.Listeners[i].AttachedRoutes = listenerStatus.AttachedRoutes
gw.Status.Listeners[i].SupportedKinds = listenerStatus.SupportedKinds
// Only have one condition in the logic
gw.Status.Listeners[i].Conditions = utils.GetNewConditions(gw.Status.Listeners[i].Conditions, listenerStatus.Conditions[0])
found = true
}
}
if !found {
gw.Status.Listeners = append(gw.Status.Listeners, listenerStatus)
}
}
if err := k8sClient.Status().Patch(ctx, gw, client.MergeFrom(gwOld)); err != nil {
return errors.Wrapf(err, "listener update failed")
}
if hasValidListener {
return nil
} else {
return fmt.Errorf("no valid listeners for %s", gw.Name)
}
}