Skip to content

Commit

Permalink
AV-206829 move gateway/route status updates to status layer
Browse files Browse the repository at this point in the history
  • Loading branch information
arihantg committed Oct 3, 2024
1 parent 95a61bd commit afba360
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 45 deletions.
2 changes: 2 additions & 0 deletions ako-gateway-api/k8s/gateway_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
gatewayexternalversions "sigs.k8s.io/gateway-api/pkg/client/informers/externalversions"

akogatewayapilib "github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/ako-gateway-api/lib"
akogatewayapiobjects "github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/ako-gateway-api/objects"
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/internal/k8s"
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/internal/lib"
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/internal/objects"
Expand Down Expand Up @@ -530,6 +531,7 @@ func (c *GatewayController) SetupGatewayApiEventHandlers(numWorkers uint32) {
namespace, _, _ := cache.SplitMetaNamespaceKey(utils.ObjKey(gw))
bkt := utils.Bkt(namespace, numWorkers)
c.workqueue[bkt].AddRateLimited(key)
akogatewayapiobjects.GatewayApiLister().DeleteGatewayToGatewayStatusMapping(utils.ObjKey(gw))
utils.AviLog.Debugf("key: %s, msg: DELETE", key)
},
UpdateFunc: func(old, obj interface{}) {
Expand Down
24 changes: 13 additions & 11 deletions ako-gateway-api/k8s/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
akogatewayapiobjects "github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/ako-gateway-api/objects"
akogatewayapistatus "github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/ako-gateway-api/status"
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/internal/lib"
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/internal/status"
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/pkg/utils"
)

Expand Down Expand Up @@ -60,7 +61,7 @@ func IsGatewayClassValid(key string, gatewayClass *gatewayv1.GatewayClass) bool
ObservedGeneration(gatewayClass.ObjectMeta.Generation).
Message("GatewayClass is valid").
SetIn(&gatewayClassStatus.Conditions)
akogatewayapistatus.Record(key, gatewayClass, &akogatewayapistatus.Status{GatewayClassStatus: gatewayClassStatus})
akogatewayapistatus.Record(key, gatewayClass, &status.Status{GatewayClassStatus: gatewayClassStatus})
utils.AviLog.Infof("key: %s, msg: GatewayClass object %s is valid", key, gatewayClass.Name)
return true
}
Expand All @@ -82,7 +83,7 @@ func IsValidGateway(key string, gateway *gatewayv1.Gateway) bool {
defaultCondition.
Message("No listeners found").
SetIn(&gatewayStatus.Conditions)
akogatewayapistatus.Record(key, gateway, &akogatewayapistatus.Status{GatewayStatus: gatewayStatus})
akogatewayapistatus.Record(key, gateway, &status.Status{GatewayStatus: gatewayStatus})
return false
}

Expand All @@ -92,7 +93,7 @@ func IsValidGateway(key string, gateway *gatewayv1.Gateway) bool {
defaultCondition.
Message("More than one address is not supported").
SetIn(&gatewayStatus.Conditions)
akogatewayapistatus.Record(key, gateway, &akogatewayapistatus.Status{GatewayStatus: gatewayStatus})
akogatewayapistatus.Record(key, gateway, &status.Status{GatewayStatus: gatewayStatus})
return false
}

Expand All @@ -101,7 +102,7 @@ func IsValidGateway(key string, gateway *gatewayv1.Gateway) bool {
defaultCondition.
Message("Only IPAddress as AddressType is supported").
SetIn(&gatewayStatus.Conditions)
akogatewayapistatus.Record(key, gateway, &akogatewayapistatus.Status{GatewayStatus: gatewayStatus})
akogatewayapistatus.Record(key, gateway, &status.Status{GatewayStatus: gatewayStatus})
return false
}

Expand All @@ -121,7 +122,7 @@ func IsValidGateway(key string, gateway *gatewayv1.Gateway) bool {
Reason(string(gatewayv1.GatewayReasonListenersNotValid)).
Message(fmt.Sprintf("Gateway contains %d invalid listener(s)", invalidListenerCount)).
SetIn(&gatewayStatus.Conditions)
akogatewayapistatus.Record(key, gateway, &akogatewayapistatus.Status{GatewayStatus: gatewayStatus})
akogatewayapistatus.Record(key, gateway, &status.Status{GatewayStatus: gatewayStatus})
return false
}

Expand All @@ -130,7 +131,7 @@ func IsValidGateway(key string, gateway *gatewayv1.Gateway) bool {
Status(metav1.ConditionTrue).
Message("Gateway configuration is valid").
SetIn(&gatewayStatus.Conditions)
akogatewayapistatus.Record(key, gateway, &akogatewayapistatus.Status{GatewayStatus: gatewayStatus})
akogatewayapistatus.Record(key, gateway, &status.Status{GatewayStatus: gatewayStatus})
utils.AviLog.Infof("key: %s, msg: Gateway %s is valid", key, gateway.Name)
return true
}
Expand Down Expand Up @@ -273,7 +274,7 @@ func IsHTTPRouteValid(key string, obj *gatewayv1.HTTPRoute) bool {
utils.AviLog.Warnf("key: %s, msg: Parent Reference %s of HTTPRoute object %s is not valid, err: %v", key, parentRefName, httpRoute.Name, err)
}
}
akogatewayapistatus.Record(key, httpRoute, &akogatewayapistatus.Status{HTTPRouteStatus: httpRouteStatus})
akogatewayapistatus.Record(key, httpRoute, &status.Status{HTTPRouteStatus: httpRouteStatus})

// No valid attachment, we can't proceed with this HTTPRoute object.
if invalidParentRefCount == len(httpRoute.Spec.ParentRefs) {
Expand Down Expand Up @@ -322,7 +323,8 @@ func validateParentReference(key string, httpRoute *gatewayv1.HTTPRoute, httpRou
Status(metav1.ConditionFalse).
ObservedGeneration(httpRoute.ObjectMeta.Generation)

if len(gateway.Status.Conditions) == 0 {
gwStatus := akogatewayapiobjects.GatewayApiLister().GetGatewayToGatewayStatusMapping(gwNsName)
if len(gwStatus.Conditions) == 0 {
// Gateway processing by AKO has not started.
utils.AviLog.Errorf("key: %s, msg: AKO is yet to process Gateway %s for parent reference %s.", key, gateway.Name, name)
err := fmt.Errorf("AKO is yet to process Gateway %s for parent reference %s", gateway.Name, name)
Expand All @@ -334,7 +336,7 @@ func validateParentReference(key string, httpRoute *gatewayv1.HTTPRoute, httpRou
}

// Attach only when gateway configuration is valid
currentGatewayStatusCondition := gateway.Status.Conditions[0]
currentGatewayStatusCondition := gwStatus.Conditions[0]
if currentGatewayStatusCondition.Status != metav1.ConditionTrue {
// Gateway is not in an expected state.
utils.AviLog.Errorf("key: %s, msg: Gateway %s for parent reference %s is in Invalid State", key, gateway.Name, name)
Expand Down Expand Up @@ -447,7 +449,7 @@ func validateParentReference(key string, httpRoute *gatewayv1.HTTPRoute, httpRou
}
return err
}
gatewayStatus := gateway.Status.DeepCopy()
gatewayStatus := gwStatus.DeepCopy()
for _, listenerObj := range listenersMatchedToRoute {
listenerName := listenerObj.Name
// Increment the attached routes of the listener in the Gateway object
Expand All @@ -465,7 +467,7 @@ func validateParentReference(key string, httpRoute *gatewayv1.HTTPRoute, httpRou

gatewayStatus.Listeners[i].AttachedRoutes += 1
}
akogatewayapistatus.Record(key, gateway, &akogatewayapistatus.Status{GatewayStatus: gatewayStatus})
akogatewayapistatus.Record(key, gateway, &status.Status{GatewayStatus: gatewayStatus})

defaultCondition.
Reason(string(gatewayv1.GatewayReasonAccepted)).
Expand Down
28 changes: 28 additions & 0 deletions ako-gateway-api/objects/gateway_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"fmt"
"sync"

gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"

"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/internal/objects"
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/pkg/utils"
)
Expand Down Expand Up @@ -47,6 +49,7 @@ func GatewayApiLister() *GWLister {
gatewayRouteToHostnameStore: objects.NewObjectMapStore(),
gatewayRouteToHTTPSPGPoolStore: objects.NewObjectMapStore(),
podToServiceStore: objects.NewObjectMapStore(),
gatewayToStatus: objects.NewObjectMapStore(),
}
})
return gwLister
Expand Down Expand Up @@ -113,6 +116,9 @@ type GWLister struct {
//Pods -> Service Mapping for NPL
//podNs/podName -> [svcNs/svcName, ...]
podToServiceStore *objects.ObjectMapStore

// namespace/gateway -> gateway Status
gatewayToStatus *objects.ObjectMapStore
}

type GatewayRouteKind struct {
Expand Down Expand Up @@ -231,6 +237,28 @@ func (g *GWLister) GetGatewayToListeners(gwNsName string) []GatewayListenerStore
return nil
}

func (g *GWLister) UpdateGatewayToGatewayStatusMapping(gwName string, gwStatus *gatewayv1.GatewayStatus) {
g.gwLock.Lock()
defer g.gwLock.Unlock()
g.gatewayToStatus.AddOrUpdate(gwName, gwStatus)
}

func (g *GWLister) DeleteGatewayToGatewayStatusMapping(gwName string) {
g.gwLock.Lock()
defer g.gwLock.Unlock()
g.gatewayToStatus.Delete(gwName)
}

func (g *GWLister) GetGatewayToGatewayStatusMapping(gwName string) *gatewayv1.GatewayStatus {
g.gwLock.RLock()
defer g.gwLock.RUnlock()
found, gatewayList := g.gatewayToStatus.Get(gwName)
if !found {
return nil
}
return gatewayList.(*gatewayv1.GatewayStatus)
}

//=====All route <-> gateway mappings go here.

func (g *GWLister) GetRouteToGateway(routeTypeNsName string) (bool, []string) {
Expand Down
40 changes: 23 additions & 17 deletions ako-gateway-api/status/gateway_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ func (o *gateway) Delete(key string, option status.StatusOptions) {
}

// assuming 1 IP per gateway
status := gw.Status.DeepCopy()
status.Addresses = []gatewayv1.GatewayStatusAddress{}
gatewayStatus := gw.Status.DeepCopy()
gatewayStatus.Addresses = []gatewayv1.GatewayStatusAddress{}

condition := NewCondition()
condition.
Expand All @@ -113,20 +113,20 @@ func (o *gateway) Delete(key string, option status.StatusOptions) {
Reason(string(gatewayv1.GatewayReasonPending)).
ObservedGeneration(gw.ObjectMeta.Generation).
Message("Virtual service has been deleted").
SetIn(&status.Conditions)
SetIn(&gatewayStatus.Conditions)

for i := range status.Listeners {
for i := range gatewayStatus.Listeners {
listenerCondition := NewCondition()
listenerCondition.
Type(string(gatewayv1.GatewayConditionProgrammed)).
Status(metav1.ConditionUnknown).
Reason(string(gatewayv1.GatewayReasonPending)).
ObservedGeneration(gw.ObjectMeta.Generation).
Message("Virtual service has been deleted").
SetIn(&status.Listeners[i].Conditions)
SetIn(&gatewayStatus.Listeners[i].Conditions)
}

o.Patch(key, gw, &Status{GatewayStatus: status})
o.Patch(key, gw, &status.Status{GatewayStatus: gatewayStatus})
utils.AviLog.Infof("key: %s, msg: Successfully reset the address status of gateway: %s", key, gw.Name)

// TODO: Add annotation delete code here
Expand All @@ -138,7 +138,12 @@ func (o *gateway) Update(key string, option status.StatusOptions) {
return
}

status := gw.Status.DeepCopy()
if option.Options != nil && option.Options.Status != nil && option.Options.Status.GatewayStatus != nil {
o.Patch(key, gw, option.Options.Status)
return
}

gatewaystatus := gw.Status.DeepCopy()
addressType := gatewayv1.IPAddressType
ipAddrs := []gatewayv1.GatewayStatusAddress{}
for _, vip := range option.Options.Vip {
Expand All @@ -147,7 +152,7 @@ func (o *gateway) Update(key string, option status.StatusOptions) {
Value: vip,
})
}
status.Addresses = ipAddrs
gatewaystatus.Addresses = ipAddrs

condition := NewCondition()
var conditionType, reason, message string
Expand All @@ -170,19 +175,19 @@ func (o *gateway) Update(key string, option status.StatusOptions) {
Reason(reason).
ObservedGeneration(gw.ObjectMeta.Generation).
Message(message).
SetIn(&status.Conditions)
SetIn(&gatewaystatus.Conditions)

for i := range status.Listeners {
for i := range gatewaystatus.Listeners {
listenerCondition := NewCondition()
listenerCondition.
Type(conditionType).
Status(conditionStatus).
Reason(reason).
ObservedGeneration(gw.ObjectMeta.Generation).
Message(message).
SetIn(&status.Listeners[i].Conditions)
SetIn(&gatewaystatus.Listeners[i].Conditions)
}
o.Patch(key, gw, &Status{GatewayStatus: status})
o.Patch(key, gw, &status.Status{GatewayStatus: gatewaystatus})

// TODO: Annotation update code here
}
Expand All @@ -193,27 +198,28 @@ func (o *gateway) BulkUpdate(key string, options []status.StatusOptions) {
for _, option := range options {
nsName := option.Options.ServiceMetadata.Gateway
if gw, ok := gwMap[nsName]; ok {
status := &gatewayv1.GatewayStatus{}
gatewaystatus := &gatewayv1.GatewayStatus{}
addressType := gatewayv1.IPAddressType
status.Addresses = append(status.Addresses, gatewayv1.GatewayStatusAddress{
gatewaystatus.Addresses = append(gatewaystatus.Addresses, gatewayv1.GatewayStatusAddress{
Type: &addressType,
Value: option.Options.Vip[0],
})
apimeta.SetStatusCondition(&status.Conditions, metav1.Condition{
apimeta.SetStatusCondition(&gatewaystatus.Conditions, metav1.Condition{
Type: string(gatewayv1.GatewayConditionProgrammed),
Status: metav1.ConditionTrue,
Reason: string(gatewayv1.GatewayReasonProgrammed),
Message: "Virtual service configured/updated",
ObservedGeneration: gw.ObjectMeta.Generation + 1,
})
o.Patch(key, gw, &Status{GatewayStatus: status})

o.Patch(key, gw, &status.Status{GatewayStatus: gatewaystatus})

// TODO: Annotation update code here
}
}
}

func (o *gateway) Patch(key string, obj runtime.Object, status *Status, retryNum ...int) {
func (o *gateway) Patch(key string, obj runtime.Object, status *status.Status, retryNum ...int) {
retry := 0
if len(retryNum) > 0 {
retry = retryNum[0]
Expand Down
2 changes: 1 addition & 1 deletion ako-gateway-api/status/gatewayclass_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (o *gatewayClass) BulkUpdate(key string, options []status.StatusOptions) {
// TODO: Add this code when we publish the status from the rest layer
}

func (o *gatewayClass) Patch(key string, obj runtime.Object, status *Status, retryNum ...int) {
func (o *gatewayClass) Patch(key string, obj runtime.Object, status *status.Status, retryNum ...int) {
retry := 0
if len(retryNum) > 0 {
retry = retryNum[0]
Expand Down
15 changes: 13 additions & 2 deletions ako-gateway-api/status/httproute_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"encoding/json"
"reflect"
"strings"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
Expand Down Expand Up @@ -65,14 +66,24 @@ func (o *httproute) Delete(key string, option status.StatusOptions) {
}

func (o *httproute) Update(key string, option status.StatusOptions) {
// TODO: Add this code when we publish the status from the rest layer
nsName := strings.Split(option.Options.ServiceMetadata.HTTPRoute, "/")
if len(nsName) != 2 {
utils.AviLog.Warnf("key: %s, msg: invalid HttpRoute name and namespace", key)
return
}
namespace := nsName[0]
name := nsName[1]
httpRoute := o.Get(key, name, namespace)
if httpRoute != nil {
o.Patch(key, httpRoute, option.Options.Status)
}
}

func (o *httproute) BulkUpdate(key string, options []status.StatusOptions) {
// TODO: Add this code when we publish the status from the rest layer
}

func (o *httproute) Patch(key string, obj runtime.Object, status *Status, retryNum ...int) {
func (o *httproute) Patch(key string, obj runtime.Object, status *status.Status, retryNum ...int) {
retry := 0
if len(retryNum) > 0 {
retry = retryNum[0]
Expand Down
Loading

0 comments on commit afba360

Please sign in to comment.