From e2cc8b466b457ae989930d5e83c277b48b208dc4 Mon Sep 17 00:00:00 2001 From: barnettZQG Date: Mon, 19 Sep 2022 10:23:10 +0800 Subject: [PATCH] Fix: query the resource duplicately (#4714) * Fix: query the resource duplicately Signed-off-by: barnettZQG * Fix: add an e2e test case Signed-off-by: barnettZQG Signed-off-by: barnettZQG --- pkg/velaql/providers/query/collector.go | 14 +++++++++++--- pkg/velaql/providers/query/endpoint.go | 2 +- pkg/velaql/providers/query/handler.go | 4 ++-- pkg/velaql/providers/query/utils.go | 23 +++++++++++++++++------ references/cli/top/model/resource.go | 2 +- test/e2e-apiserver-test/velaql_test.go | 23 +++++++++++++++++++++++ 6 files changed, 55 insertions(+), 13 deletions(-) diff --git a/pkg/velaql/providers/query/collector.go b/pkg/velaql/providers/query/collector.go index 1de2fb670..24f6ecce3 100644 --- a/pkg/velaql/providers/query/collector.go +++ b/pkg/velaql/providers/query/collector.go @@ -80,18 +80,26 @@ func (c *AppCollector) CollectResourceFromApp(ctx context.Context) ([]Resource, } // ListApplicationResources list application applied resources from tracker -func (c *AppCollector) ListApplicationResources(ctx context.Context, app *v1beta1.Application, queryTree bool) ([]*types.AppliedResource, error) { +func (c *AppCollector) ListApplicationResources(ctx context.Context, app *v1beta1.Application) ([]*types.AppliedResource, error) { rootRT, currentRT, historyRTs, _, err := resourcetracker.ListApplicationResourceTrackers(ctx, c.k8sClient, app) if err != nil { return nil, err } var managedResources []*types.AppliedResource + existResources := make(map[common.ClusterObjectReference]bool, len(app.Spec.Components)) for _, rt := range append(historyRTs, rootRT, currentRT) { if rt != nil { for _, managedResource := range rt.Spec.ManagedResources { if isResourceInTargetCluster(c.opt.Filter, managedResource.ClusterObjectReference) && isResourceInTargetComponent(c.opt.Filter, managedResource.Component) && - (queryTree || isResourceMatchKindAndVersion(c.opt.Filter, managedResource.Kind, managedResource.APIVersion)) { + (c.opt.WithTree || isResourceMatchKindAndVersion(c.opt.Filter, managedResource.Kind, managedResource.APIVersion)) { + if c.opt.WithTree { + // If we want to query the tree, we only need to query once for the same resource. + if _, exist := existResources[managedResource.ClusterObjectReference]; exist { + continue + } + existResources[managedResource.ClusterObjectReference] = true + } managedResources = append(managedResources, &types.AppliedResource{ Cluster: func() string { if managedResource.Cluster != "" { @@ -123,7 +131,7 @@ func (c *AppCollector) ListApplicationResources(ctx context.Context, app *v1beta } } - if !queryTree { + if !c.opt.WithTree { return managedResources, nil } diff --git a/pkg/velaql/providers/query/endpoint.go b/pkg/velaql/providers/query/endpoint.go index 4cbd1ac3a..daaec9e7d 100644 --- a/pkg/velaql/providers/query/endpoint.go +++ b/pkg/velaql/providers/query/endpoint.go @@ -65,7 +65,7 @@ func (h *provider) GeneratorServiceEndpoints(ctx monitorContext.Context, wfCtx w serviceEndpoints := make([]querytypes.ServiceEndpoint, 0) var clusterGatewayNodeIP = make(map[string]string) collector := NewAppCollector(h.cli, opt) - resources, err := collector.ListApplicationResources(ctx, app, opt.WithTree) + resources, err := collector.ListApplicationResources(ctx, app) if err != nil { return err } diff --git a/pkg/velaql/providers/query/handler.go b/pkg/velaql/providers/query/handler.go index 71f173498..a82143a17 100644 --- a/pkg/velaql/providers/query/handler.go +++ b/pkg/velaql/providers/query/handler.go @@ -127,7 +127,7 @@ func (h *provider) ListAppliedResources(ctx monitorContext.Context, wfCtx wfCont if err = h.cli.Get(ctx, appKey, app); err != nil { return v.FillObject(err.Error(), "err") } - appResList, err := collector.ListApplicationResources(ctx, app, opt.WithTree) + appResList, err := collector.ListApplicationResources(ctx, app) if err != nil { return v.FillObject(err.Error(), "err") } @@ -152,7 +152,7 @@ func (h *provider) CollectResources(ctx monitorContext.Context, wfCtx wfContext. if err = h.cli.Get(ctx, appKey, app); err != nil { return v.FillObject(err.Error(), "err") } - appResList, err := collector.ListApplicationResources(ctx, app, opt.WithTree) + appResList, err := collector.ListApplicationResources(ctx, app) if err != nil { return v.FillObject(err.Error(), "err") } diff --git a/pkg/velaql/providers/query/utils.go b/pkg/velaql/providers/query/utils.go index de07045b0..ec33f1f61 100644 --- a/pkg/velaql/providers/query/utils.go +++ b/pkg/velaql/providers/query/utils.go @@ -24,6 +24,7 @@ import ( "github.com/kubevela/workflow/pkg/cue/model/value" + "github.com/oam-dev/kubevela/pkg/oam" querytypes "github.com/oam-dev/kubevela/pkg/velaql/providers/query/types" ) @@ -62,11 +63,21 @@ func buildResourceArray(res querytypes.AppliedResource, parent, node *querytypes func buildResourceItem(res querytypes.AppliedResource, workload querytypes.Workload, object unstructured.Unstructured) querytypes.ResourceItem { return querytypes.ResourceItem{ - Cluster: res.Cluster, - Workload: workload, - Component: res.Component, - Object: object, - PublishVersion: res.PublishVersion, - DeployVersion: res.DeployVersion, + Cluster: res.Cluster, + Workload: workload, + Component: res.Component, + Object: object, + PublishVersion: func() string { + if object.GetAnnotations()[oam.AnnotationPublishVersion] != "" { + return object.GetAnnotations()[oam.AnnotationPublishVersion] + } + return res.PublishVersion + }(), + DeployVersion: func() string { + if object.GetAnnotations()[oam.AnnotationDeployVersion] != "" { + return object.GetAnnotations()[oam.AnnotationDeployVersion] + } + return res.DeployVersion + }(), } } diff --git a/references/cli/top/model/resource.go b/references/cli/top/model/resource.go index 38f32bc3a..b3f187835 100644 --- a/references/cli/top/model/resource.go +++ b/references/cli/top/model/resource.go @@ -61,7 +61,7 @@ func collectResource(ctx context.Context, c client.Client, opt query.Option) ([] return nil, err } collector := query.NewAppCollector(c, opt) - appResList, err := collector.ListApplicationResources(context.Background(), app, opt.WithTree) + appResList, err := collector.ListApplicationResources(context.Background(), app) if err != nil { return nil, err } diff --git a/test/e2e-apiserver-test/velaql_test.go b/test/e2e-apiserver-test/velaql_test.go index 26d5ab852..c9fccf6e0 100644 --- a/test/e2e-apiserver-test/velaql_test.go +++ b/test/e2e-apiserver-test/velaql_test.go @@ -164,6 +164,29 @@ var _ = Describe("Test velaQL rest api", func() { }, time.Minute*1, 3*time.Second).Should(BeNil()) }) + It("Test query application pod when upgrading the app", func() { + + // Create a new RT to simulate upgrading the application + rt := &v1beta1.ResourceTracker{} + Expect(k8sClient.Get(context.TODO(), types.NamespacedName{ + Name: fmt.Sprintf("%s-v1-%s", appName, namespace), + }, rt)).Should(BeNil()) + newRT := rt.DeepCopy() + newRT.Name = fmt.Sprintf("%s-v2-%s", appName, namespace) + newRT.Spec.ApplicationGeneration = 0 + newRT.UID = "" + newRT.ResourceVersion = "" + Expect(k8sClient.Create(context.TODO(), newRT)).Should(BeNil()) + queryRes := get(fmt.Sprintf("/query?velaql=%s{appName=%s,appNs=%s,name=%s}.%s", "test-component-pod-view", appName, namespace, component1Name, "status")) + status := new(Status) + fmt.Println(status.Error) + Expect(decodeResponseBody(queryRes, status)).Should(Succeed()) + Expect(len(status.PodList)).Should(Equal(1)) + Expect(status.PodList[0].Component).Should(Equal(component1Name)) + // Clear the test data + Expect(k8sClient.Delete(context.TODO(), newRT)) + }) + It("Test collect pod from cronJob", func() { cronJob := new(v1beta1.ComponentDefinition) Expect(yaml.Unmarshal([]byte(cronJobComponentDefinition), cronJob)).Should(BeNil())