From e52fbce7d529f5a02c27e8b15e3b71bb4a8ca383 Mon Sep 17 00:00:00 2001 From: Pranshu Srivastava Date: Mon, 15 May 2023 12:57:27 +0530 Subject: [PATCH] Allow field KV general matching Currently all matching support is limited to map-list representations; this adds support for a more general "key:value" based matching expression for any `interface{}` field (non-map-list-like). --- docs/customresourcestate-metrics.md | 3 +++ pkg/customresourcestate/registry_factory.go | 10 ++++++++++ pkg/customresourcestate/registry_factory_test.go | 9 +++++++++ 3 files changed, 22 insertions(+) diff --git a/docs/customresourcestate-metrics.md b/docs/customresourcestate-metrics.md index e400c50726..95ca156b3a 100644 --- a/docs/customresourcestate-metrics.md +++ b/docs/customresourcestate-metrics.md @@ -522,6 +522,9 @@ Examples: # if the value to be matched is a number or boolean, the value is compared as a number or boolean [status, conditions, "[value=66]", name] # status.conditions[1].name = "b" + +# For generally matching against a field in an object schema, use the following syntax: +[metadata, "name=foo"] # if v, ok := metadata[name]; ok && v == "foo" { return v; } else { /* ignore */ } ``` ### Wildcard matching of version and kind fields diff --git a/pkg/customresourcestate/registry_factory.go b/pkg/customresourcestate/registry_factory.go index 27db2ffe3c..a1ea43f962 100644 --- a/pkg/customresourcestate/registry_factory.go +++ b/pkg/customresourcestate/registry_factory.go @@ -623,6 +623,16 @@ func compilePath(path []string) (out valuePath, _ error) { part: part, op: func(m interface{}) interface{} { if mp, ok := m.(map[string]interface{}); ok { + kv := strings.Split(part, "=") + if len(kv) == 2 /* k=v */ { + key := kv[0] + val := kv[1] + if v, ok := mp[key]; ok { + if v == val { + return v + } + } + } return mp[part] } else if s, ok := m.([]interface{}); ok { i, err := strconv.Atoi(part) diff --git a/pkg/customresourcestate/registry_factory_test.go b/pkg/customresourcestate/registry_factory_test.go index a0432ec0bd..153fb8065e 100644 --- a/pkg/customresourcestate/registry_factory_test.go +++ b/pkg/customresourcestate/registry_factory_test.go @@ -349,6 +349,15 @@ func Test_values(t *testing.T) { newEachValue(t, 0, "type", "Provisioned"), newEachValue(t, 1, "type", "Ready"), }}, + {name: "= expression matching", each: &compiledInfo{ + compiledCommon: compiledCommon{ + labelFromPath: map[string]valuePath{ + "bar": mustCompilePath(t, "metadata", "annotations", "bar=baz"), + }, + }, + }, wantResult: []eachValue{ + newEachValue(t, 1, "bar", "baz"), + }}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {