From 6646f0984a6865ad9028601e0976a0c9b79938ed Mon Sep 17 00:00:00 2001 From: Gaurav Kumar Ghildiyal Date: Wed, 12 Jun 2024 09:09:32 -0700 Subject: [PATCH] gwctl performance improvements (#3145) * Fetch resources in bulk instead of single API calls as the default. Eg. When we have a set of HTTPRoutes and we want to fetch all Backends referenced by this HTTPRoute, it's slightly better to fetch all the Backends with one API call and then filter these out based on which are being referenced. This is in contrast with fetching each individual backend through a separate API call that is referenced by the HTTPRoutes. (Even at smaller scales, multiple API calls starts to seem inefficient) * Lazily fetch events instead of making them part of the ResourceModel. Events associated with a resource need to be fetch independently for each resource. This means the number of API calls grows linearly with the number of resources that we have. - Pre-fetching events for all resources BEFORE PRINTING ANYTHING gives the impression of the CLI being unresponsive. - Lazily fetching events allows us to print the describe-view for a single resource fully before fetching events for the next one, thereby giving the user an impression of the CLI making progress. Also, it makes sense for Events to not be part of the ResourceModel given events are just tied with a single resource and have no interdependence (so don't need some pre-calculations) --- gwctl/cmd/subcommand.go | 8 +- gwctl/pkg/printer/backends.go | 7 +- gwctl/pkg/printer/common.go | 5 + gwctl/pkg/printer/gatewayclasses.go | 7 +- gwctl/pkg/printer/gatewayclasses_test.go | 5 +- gwctl/pkg/printer/gateways.go | 7 +- gwctl/pkg/printer/gateways_test.go | 5 +- gwctl/pkg/printer/namespace.go | 7 +- gwctl/pkg/printer/namespace_test.go | 5 +- gwctl/pkg/resourcediscovery/discoverer.go | 178 ++++++---------------- gwctl/pkg/resourcediscovery/nodes.go | 15 -- 11 files changed, 85 insertions(+), 164 deletions(-) diff --git a/gwctl/cmd/subcommand.go b/gwctl/cmd/subcommand.go index 1adfff3529..964cdde341 100644 --- a/gwctl/cmd/subcommand.go +++ b/gwctl/cmd/subcommand.go @@ -217,7 +217,7 @@ func runGetOrDescribeNamespaces(f cmdutils.Factory, o *getOrDescribeOptions) { handleErrOrExitWithMsg(err, "failed to discover Namespace resources") realClock := clock.RealClock{} - nsPrinter := &printer.NamespacesPrinter{Writer: o.out, Clock: realClock} + nsPrinter := &printer.NamespacesPrinter{Writer: o.out, Clock: realClock, EventFetcher: discoverer} if o.cmdName == commandNameGet { printer.Print(nsPrinter, resourceModel, o.outputFormat) } else { @@ -248,7 +248,7 @@ func runGetOrDescribeGatewayClasses(f cmdutils.Factory, o *getOrDescribeOptions) handleErrOrExitWithMsg(err, "failed to discover GatewayClass resources") realClock := clock.RealClock{} - gwcPrinter := &printer.GatewayClassesPrinter{Writer: o.out, Clock: realClock} + gwcPrinter := &printer.GatewayClassesPrinter{Writer: o.out, Clock: realClock, EventFetcher: discoverer} if o.cmdName == commandNameGet { printer.Print(gwcPrinter, resourceModel, o.outputFormat) } else { @@ -281,7 +281,7 @@ func runGetOrDescribeGateways(f cmdutils.Factory, o *getOrDescribeOptions) { handleErrOrExitWithMsg(err, "failed to discover Gateway resources") realClock := clock.RealClock{} - gwPrinter := &printer.GatewaysPrinter{Writer: o.out, Clock: realClock} + gwPrinter := &printer.GatewaysPrinter{Writer: o.out, Clock: realClock, EventFetcher: discoverer} if o.cmdName == commandNameGet { printer.Print(gwPrinter, resourceModel, o.outputFormat) } else { @@ -347,7 +347,7 @@ func runGetOrDescribeBackends(f cmdutils.Factory, o *getOrDescribeOptions) { handleErrOrExitWithMsg(err, "failed to discover Backend resources") realClock := clock.RealClock{} - backendsPrinter := &printer.BackendsPrinter{Writer: o.out, Clock: realClock} + backendsPrinter := &printer.BackendsPrinter{Writer: o.out, Clock: realClock, EventFetcher: discoverer} if o.cmdName == commandNameGet { printer.Print(backendsPrinter, resourceModel, o.outputFormat) } else { diff --git a/gwctl/pkg/printer/backends.go b/gwctl/pkg/printer/backends.go index 36c25d699d..bb7f380462 100644 --- a/gwctl/pkg/printer/backends.go +++ b/gwctl/pkg/printer/backends.go @@ -17,6 +17,7 @@ limitations under the License. package printer import ( + "context" "fmt" "io" "strings" @@ -31,7 +32,8 @@ import ( type BackendsPrinter struct { io.Writer - Clock clock.Clock + Clock clock.Clock + EventFetcher eventFetcher } func (bp *BackendsPrinter) GetPrintableNodes(resourceModel *resourcediscovery.ResourceModel) []NodeResource { @@ -155,7 +157,8 @@ func (bp *BackendsPrinter) PrintDescribeView(resourceModel *resourcediscovery.Re } // Events - pairs = append(pairs, &DescriberKV{Key: "Events", Value: convertEventsSliceToTable(backendNode.Events, bp.Clock)}) + eventList := bp.EventFetcher.FetchEventsFor(context.Background(), backendNode.Backend) + pairs = append(pairs, &DescriberKV{Key: "Events", Value: convertEventsSliceToTable(eventList.Items, bp.Clock)}) Describe(bp, pairs) diff --git a/gwctl/pkg/printer/common.go b/gwctl/pkg/printer/common.go index b6e1f00453..f8dcdad548 100644 --- a/gwctl/pkg/printer/common.go +++ b/gwctl/pkg/printer/common.go @@ -17,6 +17,7 @@ limitations under the License. package printer import ( + "context" "fmt" "io" "os" @@ -208,3 +209,7 @@ func NodeResources[K NodeResource](items []K) []NodeResource { } return output } + +type eventFetcher interface { + FetchEventsFor(context.Context, client.Object) *corev1.EventList +} diff --git a/gwctl/pkg/printer/gatewayclasses.go b/gwctl/pkg/printer/gatewayclasses.go index 534cbfd470..c2c2ae6a0d 100644 --- a/gwctl/pkg/printer/gatewayclasses.go +++ b/gwctl/pkg/printer/gatewayclasses.go @@ -17,6 +17,7 @@ limitations under the License. package printer import ( + "context" "fmt" "io" @@ -31,7 +32,8 @@ var _ Printer = (*GatewayClassesPrinter)(nil) type GatewayClassesPrinter struct { io.Writer - Clock clock.Clock + Clock clock.Clock + EventFetcher eventFetcher } func (gcp *GatewayClassesPrinter) GetPrintableNodes(resourceModel *resourcediscovery.ResourceModel) []NodeResource { @@ -106,7 +108,8 @@ func (gcp *GatewayClassesPrinter) PrintDescribeView(resourceModel *resourcedisco pairs = append(pairs, &DescriberKV{Key: "DirectlyAttachedPolicies", Value: convertPolicyRefsToTable(policyRefs)}) // Events - pairs = append(pairs, &DescriberKV{Key: "Events", Value: convertEventsSliceToTable(gatewayClassNode.Events, gcp.Clock)}) + eventList := gcp.EventFetcher.FetchEventsFor(context.Background(), gatewayClassNode.GatewayClass) + pairs = append(pairs, &DescriberKV{Key: "Events", Value: convertEventsSliceToTable(eventList.Items, gcp.Clock)}) Describe(gcp, pairs) diff --git a/gwctl/pkg/printer/gatewayclasses_test.go b/gwctl/pkg/printer/gatewayclasses_test.go index cdcdad9c32..0a76050422 100644 --- a/gwctl/pkg/printer/gatewayclasses_test.go +++ b/gwctl/pkg/printer/gatewayclasses_test.go @@ -331,8 +331,9 @@ Events: } gcp := &GatewayClassesPrinter{ - Writer: buff, - Clock: fakeClock, + Writer: buff, + Clock: fakeClock, + EventFetcher: discoverer, } gcp.PrintDescribeView(resourceModel) diff --git a/gwctl/pkg/printer/gateways.go b/gwctl/pkg/printer/gateways.go index ad1809315b..243c1159e3 100644 --- a/gwctl/pkg/printer/gateways.go +++ b/gwctl/pkg/printer/gateways.go @@ -17,6 +17,7 @@ limitations under the License. package printer import ( + "context" "fmt" "io" "strings" @@ -32,7 +33,8 @@ var _ Printer = (*GatewaysPrinter)(nil) type GatewaysPrinter struct { io.Writer - Clock clock.Clock + Clock clock.Clock + EventFetcher eventFetcher } func (gp *GatewaysPrinter) GetPrintableNodes(resourceModel *resourcediscovery.ResourceModel) []NodeResource { @@ -152,7 +154,8 @@ func (gp *GatewaysPrinter) PrintDescribeView(resourceModel *resourcediscovery.Re } // Events - pairs = append(pairs, &DescriberKV{Key: "Events", Value: convertEventsSliceToTable(gatewayNode.Events, gp.Clock)}) + eventList := gp.EventFetcher.FetchEventsFor(context.Background(), gatewayNode.Gateway) + pairs = append(pairs, &DescriberKV{Key: "Events", Value: convertEventsSliceToTable(eventList.Items, gp.Clock)}) Describe(gp, pairs) diff --git a/gwctl/pkg/printer/gateways_test.go b/gwctl/pkg/printer/gateways_test.go index fcdd71f9b9..0306738a9f 100644 --- a/gwctl/pkg/printer/gateways_test.go +++ b/gwctl/pkg/printer/gateways_test.go @@ -485,8 +485,9 @@ func TestGatewaysPrinter_PrintDescribeView(t *testing.T) { } gp := &GatewaysPrinter{ - Writer: buff, - Clock: fakeClock, + Writer: buff, + Clock: fakeClock, + EventFetcher: discoverer, } gp.PrintDescribeView(resourceModel) diff --git a/gwctl/pkg/printer/namespace.go b/gwctl/pkg/printer/namespace.go index b292c701f6..50072ab508 100644 --- a/gwctl/pkg/printer/namespace.go +++ b/gwctl/pkg/printer/namespace.go @@ -17,6 +17,7 @@ limitations under the License. package printer import ( + "context" "fmt" "io" @@ -31,7 +32,8 @@ var _ Printer = (*NamespacesPrinter)(nil) type NamespacesPrinter struct { io.Writer - Clock clock.Clock + Clock clock.Clock + EventFetcher eventFetcher } func (nsp *NamespacesPrinter) GetPrintableNodes(resourceModel *resourcediscovery.ResourceModel) []NodeResource { @@ -94,7 +96,8 @@ func (nsp *NamespacesPrinter) PrintDescribeView(resourceModel *resourcediscovery pairs = append(pairs, &DescriberKV{Key: "DirectlyAttachedPolicies", Value: convertPolicyRefsToTable(policyRefs)}) // Events - pairs = append(pairs, &DescriberKV{Key: "Events", Value: convertEventsSliceToTable(namespaceNode.Events, nsp.Clock)}) + eventList := nsp.EventFetcher.FetchEventsFor(context.Background(), namespaceNode.Namespace) + pairs = append(pairs, &DescriberKV{Key: "Events", Value: convertEventsSliceToTable(eventList.Items, nsp.Clock)}) Describe(nsp, pairs) diff --git a/gwctl/pkg/printer/namespace_test.go b/gwctl/pkg/printer/namespace_test.go index 2bc571e93f..68fc8bc773 100644 --- a/gwctl/pkg/printer/namespace_test.go +++ b/gwctl/pkg/printer/namespace_test.go @@ -282,8 +282,9 @@ func TestNamespacePrinter_PrintDescribeView(t *testing.T) { } nsp := &NamespacesPrinter{ - Writer: buff, - Clock: fakeClock, + Writer: buff, + Clock: fakeClock, + EventFetcher: discoverer, } nsp.PrintDescribeView(resourceModel) diff --git a/gwctl/pkg/resourcediscovery/discoverer.go b/gwctl/pkg/resourcediscovery/discoverer.go index d67db420b5..afa06c7a83 100644 --- a/gwctl/pkg/resourcediscovery/discoverer.go +++ b/gwctl/pkg/resourcediscovery/discoverer.go @@ -30,7 +30,6 @@ import ( "sigs.k8s.io/gateway-api/gwctl/pkg/relations" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/fields" @@ -63,11 +62,6 @@ type Filter struct { // Discoverer orchestrates the discovery of resources and their associated // policies, building a model of interconnected resources. -// -// TODO: Optimization Task: Implement a heuristic within each discovery function -// to intelligently choose between: -// - Single API calls for efficient bulk fetching when appropriate. -// - Multiple API calls for targeted retrieval when necessary. type Discoverer struct { K8sClients *common.K8sClients PolicyManager *policymanager.PolicyManager @@ -141,8 +135,6 @@ func (d Discoverer) DiscoverResourcesForGatewayClass(filter Filter) (*ResourceMo } resourceModel.addGatewayClasses(gatewayClasses...) - d.discoverEventsForGatewayClasses(ctx, resourceModel) - d.discoverGatewaysForGatewayClasses(ctx, resourceModel) d.discoverPolicies(resourceModel) @@ -160,8 +152,6 @@ func (d Discoverer) DiscoverResourcesForGateway(filter Filter) (*ResourceModel, } resourceModel.addGateways(gateways...) - d.discoverEventsForGateways(ctx, resourceModel) - d.discoverHTTPRoutesForGateways(ctx, resourceModel) d.discoverBackendsForHTTPRoutes(ctx, resourceModel) d.discoverGatewayClassesForGateways(ctx, resourceModel) @@ -186,8 +176,6 @@ func (d Discoverer) DiscoverResourcesForHTTPRoute(filter Filter) (*ResourceModel } resourceModel.addHTTPRoutes(httpRoutes...) - d.discoverEventsForHTTPRoutes(ctx, resourceModel) - d.discoverBackendsForHTTPRoutes(ctx, resourceModel) d.discoverGatewaysForHTTPRoutes(ctx, resourceModel) d.discoverGatewayClassesForGateways(ctx, resourceModel) @@ -212,8 +200,6 @@ func (d Discoverer) DiscoverResourcesForBackend(filter Filter) (*ResourceModel, } resourceModel.addBackends(backends...) - d.discoverEventsForBackends(ctx, resourceModel) - d.discoverReferenceGrantsForBackends(ctx, resourceModel) d.discoverHTTPRoutesForBackends(ctx, resourceModel) d.discoverGatewaysForHTTPRoutes(ctx, resourceModel) @@ -239,8 +225,6 @@ func (d Discoverer) DiscoverResourcesForNamespace(filter Filter) (*ResourceModel } resourceModel.addNamespace(namespaces...) - d.discoverEventsForNamespaces(ctx, resourceModel) - d.discoverPolicies(resourceModel) return resourceModel, nil @@ -278,17 +262,12 @@ func (d Discoverer) discoverGatewayClassesForGateways(ctx context.Context, resou if err != nil { klog.V(1).ErrorS(err, "Failed to list all GatewayClasses") } - - // Build temporary index for GatewayClasses - gatewayClassesByID := make(map[gatewayClassID]gatewayv1.GatewayClass) - for _, gatewayClass := range gatewayClasses { - gatewayClassesByID[GatewayClassID(gatewayClass.GetName())] = gatewayClass - } + resourceModel.addGatewayClasses(gatewayClasses...) for gatewayID, gatewayNode := range resourceModel.Gateways { gatewayClassName := relations.FindGatewayClassNameForGateway(*gatewayNode.Gateway) gwcID := GatewayClassID(gatewayClassName) - gatewayClass, ok := gatewayClassesByID[gwcID] + _, ok := resourceModel.GatewayClasses[gwcID] if !ok { err := ReferenceToNonExistentResourceError{ReferenceFromTo: ReferenceFromTo{ ReferringObject: common.ObjRef{Kind: "Gateway", Name: gatewayNode.Gateway.GetName(), Namespace: gatewayNode.Gateway.GetNamespace()}, @@ -298,50 +277,49 @@ func (d Discoverer) discoverGatewayClassesForGateways(ctx context.Context, resou klog.V(1).Info(err) continue } - - resourceModel.addGatewayClasses(gatewayClass) resourceModel.connectGatewayWithGatewayClass(gatewayID, gwcID) } + + // Remove GatewayClasses which are not connected to any Gateways. + for gatewayClassID, gatewayClassNode := range resourceModel.GatewayClasses { + if len(gatewayClassNode.Gateways) == 0 { + delete(resourceModel.GatewayClasses, gatewayClassID) + } + } } // discoverGatewaysForHTTPRoutes will add Gateways associated with HTTPRoutes // in the resourceModel. func (d Discoverer) discoverGatewaysForHTTPRoutes(ctx context.Context, resourceModel *ResourceModel) { + gateways, err := d.fetchGateways(ctx, Filter{ /* every gateway */ }) + if err != nil { + klog.V(1).ErrorS(err, "Failed to fetch Gateways") + return + } + resourceModel.addGateways(gateways...) + // Visit all gateways corresponding to the httpRoutes - for _, httpRouteNode := range resourceModel.HTTPRoutes { + for httpRouteID, httpRouteNode := range resourceModel.HTTPRoutes { for _, gatewayRef := range relations.FindGatewayRefsForHTTPRoute(*httpRouteNode.HTTPRoute) { - // Check if Gateway already exists in the resourceModel. - if _, ok := resourceModel.Gateways[GatewayID(gatewayRef.Namespace, gatewayRef.Name)]; ok { - // Gateway already exists in the resourceModel, skip re-fetching. - continue - } - - // Gateway doesn't already exist so fetch and add it to the resourceModel. - gateways, err := d.fetchGateways(ctx, Filter{Namespace: gatewayRef.Namespace, Name: gatewayRef.Name, Labels: labels.Everything()}) - if err != nil { - if apierrors.IsNotFound(err) { - err := ReferenceToNonExistentResourceError{ReferenceFromTo: ReferenceFromTo{ - ReferringObject: common.ObjRef{Kind: "HTTPRoute", Name: httpRouteNode.HTTPRoute.GetName(), Namespace: httpRouteNode.HTTPRoute.GetNamespace()}, - ReferredObject: common.ObjRef{Kind: "Gateway", Name: gatewayRef.Name, Namespace: gatewayRef.Namespace}, - }} - httpRouteNode.Errors = append(httpRouteNode.Errors, err) - klog.V(1).Info(err) - } else { - klog.V(1).ErrorS(err, "Error while fetching Gateway for HTTPRoute", - "gateway", gatewayRef.String(), - "httproute", httpRouteNode.HTTPRoute.GetNamespace()+"/"+httpRouteNode.HTTPRoute.GetName(), - ) - } + gatewayID := GatewayID(gatewayRef.Namespace, gatewayRef.Name) + _, ok := resourceModel.Gateways[gatewayID] + if !ok { + err := ReferenceToNonExistentResourceError{ReferenceFromTo: ReferenceFromTo{ + ReferringObject: common.ObjRef{Kind: "HTTPRoute", Name: httpRouteNode.HTTPRoute.GetName(), Namespace: httpRouteNode.HTTPRoute.GetNamespace()}, + ReferredObject: common.ObjRef{Kind: "Gateway", Name: gatewayRef.Name, Namespace: gatewayRef.Namespace}, + }} + httpRouteNode.Errors = append(httpRouteNode.Errors, err) + klog.V(1).Info(err) continue } - resourceModel.addGateways(gateways[0]) + resourceModel.connectHTTPRouteWithGateway(httpRouteID, gatewayID) } } - // Connect gatewayd with httproutes. - for httpRouteID, httpRouteNode := range resourceModel.HTTPRoutes { - for _, gatewayRef := range relations.FindGatewayRefsForHTTPRoute(*httpRouteNode.HTTPRoute) { - resourceModel.connectHTTPRouteWithGateway(httpRouteID, GatewayID(gatewayRef.Namespace, gatewayRef.Name)) + // Remove Gateways which are not connected to any HTTPRoutes. + for gatewayID, gatewayNode := range resourceModel.Gateways { + if len(gatewayNode.HTTPRoutes) == 0 { + delete(resourceModel.Gateways, gatewayID) } } } @@ -460,43 +438,17 @@ func (d Discoverer) discoverHTTPRoutesForBackends(ctx context.Context, resourceM // HTTPRoute in the resourceModel. func (d Discoverer) discoverBackendsForHTTPRoutes(ctx context.Context, resourceModel *ResourceModel) { // This will be a three step process: - // 1. Add ALL Backends to the resourceModel that are referenced by the - // HTTPRoutes. + // 1. Add ALL Backends to the resourceModel. // 2. Discover ReferenceGrants for those Backends. // 3. Remove Backends from the resourceModel which are in a different namespace // from the HTTPRoute and are not exposed through a ReferenceGrant. // Step 1 - for _, httpRouteNode := range resourceModel.HTTPRoutes { - for _, backendRef := range relations.FindBackendRefsForHTTPRoute(*httpRouteNode.HTTPRoute) { - // Check if the Backend already exists in the resourceModel - backendID := BackendID(backendRef.Group, backendRef.Kind, backendRef.Namespace, backendRef.Name) - if _, ok := resourceModel.Backends[backendID]; ok { - // Backend already exists in the resourceModel, skip re-fetching. - continue - } - - // Backend doesn't already exist so fetch and add it to the resourceModel. - backends, err := d.fetchBackends(ctx, Filter{Namespace: backendRef.Namespace, Name: backendRef.Name}) - if err != nil { - if apierrors.IsNotFound(err) { - err := ReferenceToNonExistentResourceError{ReferenceFromTo: ReferenceFromTo{ - ReferringObject: common.ObjRef{Kind: "HTTPRoute", Name: httpRouteNode.HTTPRoute.GetName(), Namespace: httpRouteNode.HTTPRoute.GetNamespace()}, - ReferredObject: backendRef, - }} - httpRouteNode.Errors = append(httpRouteNode.Errors, err) - klog.V(1).Info(err) - } else { - klog.V(1).ErrorS(err, "Error while fetching Backend for HTTPRoute", - "backend", fmt.Sprintf("%v/%v/%v", backendRef.Kind, backendRef.Namespace, backendRef.Name), - "httproute", httpRouteNode.HTTPRoute.GetNamespace()+"/"+httpRouteNode.HTTPRoute.GetName(), - ) - } - continue - } - resourceModel.addBackends(backends[0]) - } + backends, err := d.fetchBackends(ctx, Filter{ /* All Backends */ }) + if err != nil { + klog.V(1).ErrorS(err, "Failed to list all Backends") } + resourceModel.addBackends(backends...) // Step 2 d.discoverReferenceGrantsForBackends(ctx, resourceModel) @@ -508,9 +460,12 @@ func (d Discoverer) discoverBackendsForHTTPRoutes(ctx context.Context, resourceM backendID := BackendID(backendRef.Group, backendRef.Kind, backendRef.Namespace, backendRef.Name) backendNode, ok := resourceModel.Backends[backendID] if !ok { - // Backend does not exist in the resourceModel (maybe because of some - // error), so skip processing this backend. - klog.V(3).ErrorS(nil, "Backend not found in the resourceModel", "backend", fmt.Sprintf("%v/%v/%v", backendRef.Kind, backendRef.Namespace, backendRef.Name)) + err := ReferenceToNonExistentResourceError{ReferenceFromTo: ReferenceFromTo{ + ReferringObject: common.ObjRef{Kind: "HTTPRoute", Name: httpRouteNode.HTTPRoute.GetName(), Namespace: httpRouteNode.HTTPRoute.GetNamespace()}, + ReferredObject: backendRef, + }} + httpRouteNode.Errors = append(httpRouteNode.Errors, err) + klog.V(1).Info(err) continue } @@ -541,8 +496,8 @@ func (d Discoverer) discoverBackendsForHTTPRoutes(ctx context.Context, resourceM } } - // At this point, we know that either in the same namespace as the - // HTTPRoute, or is exposed through a ReferenceGrant. + // At this point, we know that either Backend is in the same namespace as + // the HTTPRoute, or is exposed through a ReferenceGrant. resourceModel.connectHTTPRouteWithBackend(HTTPRouteID(httpRouteNode.HTTPRoute.GetNamespace(), httpRouteNode.HTTPRoute.GetName()), backendID) } } @@ -595,6 +550,7 @@ func (d Discoverer) discoverReferenceGrantsForBackends(ctx context.Context, reso fmt.Fprintf(os.Stderr, "failed to fetch list of ReferenceGrants: %v\n", err) os.Exit(1) } + referenceGrantsByNamespace[backendNS] = referenceGrants } for _, referenceGrant := range referenceGrants { @@ -621,46 +577,6 @@ func (d Discoverer) discoverPolicies(resourceModel *ResourceModel) { resourceModel.addPolicyIfTargetExists(d.PolicyManager.GetPolicies()...) } -// discoverEventsForGatewayClasses adds Events associated with GatewayClasses -// that exist in the resourceModel. -func (d Discoverer) discoverEventsForGatewayClasses(ctx context.Context, resourceModel *ResourceModel) { - for _, gatewayClassNode := range resourceModel.GatewayClasses { - gatewayClassNode.Events = append(gatewayClassNode.Events, d.fetchEventsFor(ctx, gatewayClassNode.GatewayClass).Items...) - } -} - -// discoverEventsForGateways adds Events associated with Gateways that exist in -// the resourceModel. -func (d Discoverer) discoverEventsForGateways(ctx context.Context, resourceModel *ResourceModel) { - for _, gatewayNode := range resourceModel.Gateways { - gatewayNode.Events = append(gatewayNode.Events, d.fetchEventsFor(ctx, gatewayNode.Gateway).Items...) - } -} - -// discoverEventsForHTTPRoutes adds Events associated with HTTPRoutes that exist -// in the resourceModel. -func (d Discoverer) discoverEventsForHTTPRoutes(ctx context.Context, resourceModel *ResourceModel) { - for _, httpRouteNode := range resourceModel.HTTPRoutes { - httpRouteNode.Events = append(httpRouteNode.Events, d.fetchEventsFor(ctx, httpRouteNode.HTTPRoute).Items...) - } -} - -// discoverEventsForBackends adds Events associated with Backends that exist in -// the resourceModel. -func (d Discoverer) discoverEventsForBackends(ctx context.Context, resourceModel *ResourceModel) { - for _, backendNode := range resourceModel.Backends { - backendNode.Events = append(backendNode.Events, d.fetchEventsFor(ctx, backendNode.Backend).Items...) - } -} - -// discoverEventsForNamespaces adds Events associated with Namespaces that exist -// in the resourceModel. -func (d Discoverer) discoverEventsForNamespaces(ctx context.Context, resourceModel *ResourceModel) { - for _, nsNode := range resourceModel.Namespaces { - nsNode.Events = append(nsNode.Events, d.fetchEventsFor(ctx, nsNode.Namespace).Items...) - } -} - // fetchGatewayClasses fetches GatewayClasses based on a filter. func (d Discoverer) fetchGatewayClasses(ctx context.Context, filter Filter) ([]gatewayv1.GatewayClass, error) { gvr := schema.GroupVersionResource{ @@ -790,7 +706,7 @@ func (d Discoverer) fetchHTTPRoutes(ctx context.Context, filter Filter) ([]gatew return httpRouteList.Items, nil } -// fetchHTTPRoutes fetches HTTPRoutes based on a filter. +// fetchReferenceGrants fetches ReferenceGrants based on a filter. func (d Discoverer) fetchReferenceGrants(ctx context.Context, filter Filter) ([]gatewayv1beta1.ReferenceGrant, error) { gvr := schema.GroupVersionResource{ Group: defaultReferenceGrantGroupVersion.Group, @@ -894,7 +810,7 @@ func (d Discoverer) fetchNamespace(ctx context.Context, filter Filter) ([]corev1 } // fetchEventsFor fetches events associated with the given object. -func (d Discoverer) fetchEventsFor(ctx context.Context, object client.Object) *corev1.EventList { +func (d Discoverer) FetchEventsFor(ctx context.Context, object client.Object) *corev1.EventList { eventList := &corev1.EventList{} options := &client.ListOptions{ FieldSelector: fields.AndSelectors( diff --git a/gwctl/pkg/resourcediscovery/nodes.go b/gwctl/pkg/resourcediscovery/nodes.go index 652425b9e7..5c6ad896a1 100644 --- a/gwctl/pkg/resourcediscovery/nodes.go +++ b/gwctl/pkg/resourcediscovery/nodes.go @@ -133,8 +133,6 @@ type GatewayClassNode struct { Gateways map[gatewayID]*GatewayNode // Policies stores Policies that directly apply to this GatewayClass. Policies map[policyID]*PolicyNode - // Events contains the events associated with this Gateway. - Events []corev1.Event } func NewGatewayClassNode(gatewayClass *gatewayv1.GatewayClass) *GatewayClassNode { @@ -142,7 +140,6 @@ func NewGatewayClassNode(gatewayClass *gatewayv1.GatewayClass) *GatewayClassNode GatewayClass: gatewayClass, Gateways: make(map[gatewayID]*GatewayNode), Policies: make(map[policyID]*PolicyNode), - Events: []corev1.Event{}, } } @@ -172,8 +169,6 @@ type GatewayNode struct { // EffectivePolicies reflects the effective policies applicable to this Gateway, // considering inheritance and hierarchy. EffectivePolicies map[policymanager.PolicyCrdID]policymanager.Policy - // Events contains the events associated with this Gateway. - Events []corev1.Event // Errors contains any errorrs associated with this resource. Errors []error } @@ -184,7 +179,6 @@ func NewGatewayNode(gateway *gatewayv1.Gateway) *GatewayNode { HTTPRoutes: make(map[httpRouteID]*HTTPRouteNode), Policies: make(map[policyID]*PolicyNode), EffectivePolicies: make(map[policymanager.PolicyCrdID]policymanager.Policy), - Events: []corev1.Event{}, Errors: []error{}, } } @@ -217,8 +211,6 @@ type HTTPRouteNode struct { // EffectivePolicies reflects the effective policies applicable to this // HTTPRoute, mapped per Gateway for context-specific enforcement. EffectivePolicies map[gatewayID]map[policymanager.PolicyCrdID]policymanager.Policy - // Events contains the events associated with this Gateway. - Events []corev1.Event // Errors contains any errorrs associated with this resource. Errors []error } @@ -230,7 +222,6 @@ func NewHTTPRouteNode(httpRoute *gatewayv1.HTTPRoute) *HTTPRouteNode { Backends: make(map[backendID]*BackendNode), Policies: make(map[policyID]*PolicyNode), EffectivePolicies: make(map[gatewayID]map[policymanager.PolicyCrdID]policymanager.Policy), - Events: []corev1.Event{}, Errors: []error{}, } } @@ -264,8 +255,6 @@ type BackendNode struct { // EffectivePolicies reflects the effective policies applicable to this // Backend, mapped per Gateway for context-specific enforcement. EffectivePolicies map[gatewayID]map[policymanager.PolicyCrdID]policymanager.Policy - // Events contains the events associated with this Gateway. - Events []corev1.Event // Errors contains any errorrs associated with this resource. Errors []error } @@ -277,7 +266,6 @@ func NewBackendNode(backend *unstructured.Unstructured) *BackendNode { Policies: make(map[policyID]*PolicyNode), ReferenceGrants: make(map[referenceGrantID]*ReferenceGrantNode), EffectivePolicies: make(map[gatewayID]map[policymanager.PolicyCrdID]policymanager.Policy), - Events: []corev1.Event{}, Errors: []error{}, } } @@ -310,8 +298,6 @@ type NamespaceNode struct { Backends map[backendID]*BackendNode // Policies stores Policies directly applied to the Namespace. Policies map[policyID]*PolicyNode - // Events contains the events associated with this Gateway. - Events []corev1.Event } func NewNamespaceNode(namespace corev1.Namespace) *NamespaceNode { @@ -324,7 +310,6 @@ func NewNamespaceNode(namespace corev1.Namespace) *NamespaceNode { HTTPRoutes: make(map[httpRouteID]*HTTPRouteNode), Backends: make(map[backendID]*BackendNode), Policies: make(map[policyID]*PolicyNode), - Events: []corev1.Event{}, } }