From d60312b81908737bd388953a191db6acaf6698a0 Mon Sep 17 00:00:00 2001 From: Aditya Thebe Date: Mon, 9 Sep 2024 19:09:47 +0545 Subject: [PATCH] feat: support multiple valeus per label on config summary search --- query/config.go | 19 +++++++++++++------ tests/config_summary_test.go | 29 ++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/query/config.go b/query/config.go index fe7fbc72..62597b6c 100644 --- a/query/config.go +++ b/query/config.go @@ -220,15 +220,22 @@ func (t ConfigSummaryRequest) healthClause() []clause.Expression { func (t *ConfigSummaryRequest) filterClause(q *gorm.DB) *gorm.DB { var orClause *gorm.DB for k, v := range t.Filter { - if strings.HasPrefix(v, "!") { - excludeValue := strings.TrimPrefix(v, "!") - q = q.Where("NOT (config_items.labels @> ?)", types.JSONStringMap{k: excludeValue}) - } else { + in, notIN, _, _, _ := ParseFilteringQuery(v, true) + + if len(notIN) > 0 { + for _, excludeValue := range notIN { + q = q.Where("NOT (config_items.labels @> ?)", types.JSONStringMap{k: excludeValue.(string)}) + } + } + + if len(in) > 0 { if orClause == nil { orClause = q } - orClause = orClause.Or("config_items.labels @> ?", types.JSONStringMap{k: v}) + for _, includeValue := range in { + orClause = orClause.Or("config_items.labels @> ?", types.JSONStringMap{k: includeValue.(string)}) + } } } @@ -324,7 +331,7 @@ func ConfigSummary(ctx context.Context, req ConfigSummaryRequest) (types.JSON, e withClauses = append(withClauses, exclause.NewWith("summary", summaryQuery)) var res []types.JSON - if err := ctx.DB().Clauses(withClauses...).Select("json_agg(row_to_json(summary))").Table("summary").Scan(&res).Error; err != nil { + if err := ctx.DB().Debug().Clauses(withClauses...).Select("json_agg(row_to_json(summary))").Table("summary").Scan(&res).Error; err != nil { return nil, err } diff --git a/tests/config_summary_test.go b/tests/config_summary_test.go index 25dccd21..6855d44f 100644 --- a/tests/config_summary_test.go +++ b/tests/config_summary_test.go @@ -105,10 +105,9 @@ var _ = ginkgo.Describe("Config Summary Search", ginkgo.Ordered, func() { ginkgo.It("should handle exclude queries", func() { request := query.ConfigSummaryRequest{ Filter: map[string]string{ - "environment": "production", - "account": "!flanksource", - "owner": "!team-1", - "database": "!logistics", + "environment": "!development,!testing", + "account": "flanksource", + "telemetry": "enabled", }, } @@ -122,7 +121,27 @@ var _ = ginkgo.Describe("Config Summary Search", ginkgo.Ordered, func() { types := lo.Map(output, func(item map[string]any, _ int) string { return item["type"].(string) }) - Expect(types).To(ConsistOf([]string{"Logistics::UI::Deployment", "Logistics::Worker::Deployment"})) + + withLabels := lo.Filter(dummy.AllDummyConfigs, func(item models.ConfigItem, _ int) bool { + env := lo.FromPtr(item.Labels)["environment"] + if env == "development" || env == "testing" { + return false + } + + if lo.FromPtr(item.Labels)["account"] == "flanksource" { + return true + } + + if lo.FromPtr(item.Labels)["telemetry"] == "enabled" { + return true + } + + return false + }) + expected := lo.Uniq(lo.Map(withLabels, func(item models.ConfigItem, _ int) string { + return lo.FromPtr(item.Type) + })) + Expect(types).To(ConsistOf(expected)) }) })