feat: Add experimental filters to trigger describe cmd (#1794)

* feat: Add cesql filter field to trigger describe cmd

* Refactor trigger describe based on defined fields in filter

* Fix comment typo

* Refactor without reflection
This commit is contained in:
David Simansky 2023-04-19 10:54:38 +02:00 committed by GitHub
parent 7e90298d92
commit e2513545b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 220 additions and 1 deletions

View File

@ -19,7 +19,6 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"knative.dev/client/lib/printing" "knative.dev/client/lib/printing"
"knative.dev/client/pkg/kn/commands" "knative.dev/client/pkg/kn/commands"
"knative.dev/client/pkg/printers" "knative.dev/client/pkg/printers"
@ -123,4 +122,65 @@ func writeTrigger(dw printers.PrefixWriter, trigger *v1beta1.Trigger, printDetai
subWriter.WriteAttribute(key, value) subWriter.WriteAttribute(key, value)
} }
} }
if len(trigger.Spec.Filters) > 0 {
// Split 'Filter' and 'Filters (experimental)' with new line
dw.WriteLine()
subWriter := dw.WriteAttribute("Filters (experimental)", "")
for _, filter := range trigger.Spec.Filters {
writeNestedFilters(subWriter, filter)
}
}
}
// writeNestedFilters goes through SubscriptionsAPIFilter and writes its content accordingly
func writeNestedFilters(dw printers.PrefixWriter, filter v1beta1.SubscriptionsAPIFilter) {
// All []SubscriptionsAPIFilter
if len(filter.All) > 0 {
// create new indentation after name
subWriter := dw.WriteAttribute("all", "")
for _, nestedFilter := range filter.All {
writeNestedFilters(subWriter, nestedFilter)
}
}
// Any []SubscriptionsAPIFilter
if len(filter.Any) > 0 {
// create new indentation after name
subWriter := dw.WriteAttribute("any", "")
for _, nestedFilter := range filter.Any {
writeNestedFilters(subWriter, nestedFilter)
}
}
// Not *SubscriptionsAPIFilter
if filter.Not != nil {
subWriter := dw.WriteAttribute("not", "")
writeNestedFilters(subWriter, *filter.Not)
}
// Exact map[string]string
if len(filter.Exact) > 0 {
// create new indentation after name
subWriter := dw.WriteAttribute("exact", "")
for k, v := range filter.Exact {
subWriter.WriteAttribute(k, v)
}
}
// Prefix map[string]string
if len(filter.Prefix) > 0 {
// create new indentation after name
subWriter := dw.WriteAttribute("prefix", "")
for k, v := range filter.Prefix {
subWriter.WriteAttribute(k, v)
}
}
// Suffix map[string]string
if len(filter.Suffix) > 0 {
// create new indentation after name
subWriter := dw.WriteAttribute("suffix", "")
for k, v := range filter.Suffix {
subWriter.WriteAttribute(k, v)
}
}
// CESQL string
if filter.CESQL != "" {
dw.WriteAttribute("cesql", filter.CESQL)
}
} }

View File

@ -15,10 +15,13 @@
package trigger package trigger
import ( import (
"bytes"
"encoding/json" "encoding/json"
"errors" "errors"
"testing" "testing"
"knative.dev/client/pkg/printers"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
"gotest.tools/v3/assert/cmp" "gotest.tools/v3/assert/cmp"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -48,6 +51,7 @@ func TestSimpleDescribe(t *testing.T) {
assert.Assert(t, util.ContainsAll(out, "Broker:", "mybroker")) assert.Assert(t, util.ContainsAll(out, "Broker:", "mybroker"))
assert.Assert(t, util.ContainsAll(out, "Filter:", "type", "foo.type.knative", "source", "src.eventing.knative")) assert.Assert(t, util.ContainsAll(out, "Filter:", "type", "foo.type.knative", "source", "src.eventing.knative"))
assert.Assert(t, util.ContainsAll(out, "Filters", "experimental", "cesql", "LOWER", "type"))
assert.Assert(t, util.ContainsAll(out, "Sink:", "Service", "myservicenamespace", "mysvc")) assert.Assert(t, util.ContainsAll(out, "Sink:", "Service", "myservicenamespace", "mysvc"))
}) })
@ -112,6 +116,158 @@ func TestDescribeTriggerMachineReadable(t *testing.T) {
recorder.Validate() recorder.Validate()
} }
func TestWriteNestedFilters(t *testing.T) {
testCases := []struct {
name string
filter v1beta1.SubscriptionsAPIFilter
expectedOutput string
}{
{
name: "Exact filter",
filter: v1beta1.SubscriptionsAPIFilter{
Exact: map[string]string{
"type": "example"}},
expectedOutput: "exact: \n" +
" type: example\n",
},
{
name: "Prefix filter",
filter: v1beta1.SubscriptionsAPIFilter{
Prefix: map[string]string{
"type": "foo.bar"}},
expectedOutput: "" +
"prefix: \n" +
" type: foo.bar\n",
},
{
name: "Suffix filter",
filter: v1beta1.SubscriptionsAPIFilter{
Suffix: map[string]string{
"type": "foo.bar"}},
expectedOutput: "" +
"suffix: \n" +
" type: foo.bar\n",
},
{
name: "All filter",
filter: v1beta1.SubscriptionsAPIFilter{
All: []v1beta1.SubscriptionsAPIFilter{
{Exact: map[string]string{
"type": "foo.bar"}},
{Prefix: map[string]string{
"source": "foo"}},
{Suffix: map[string]string{
"subject": "test"}}}},
expectedOutput: "" +
"all: \n" +
" exact: \n" +
" type: foo.bar\n" +
" prefix: \n" +
" source: foo\n" +
" suffix: \n" +
" subject: test\n",
},
{
name: "Any filter",
filter: v1beta1.SubscriptionsAPIFilter{
Any: []v1beta1.SubscriptionsAPIFilter{
{Exact: map[string]string{
"type": "foo.bar"}},
{Prefix: map[string]string{
"source": "foo"}},
{Suffix: map[string]string{
"subject": "test"}}},
},
expectedOutput: "" +
"any: \n" +
" exact: \n" +
" type: foo.bar\n" +
" prefix: \n" +
" source: foo\n" +
" suffix: \n" +
" subject: test\n",
},
{
name: "Nested All filter",
filter: v1beta1.SubscriptionsAPIFilter{
All: []v1beta1.SubscriptionsAPIFilter{
{Exact: map[string]string{
"type": "foo.bar"}},
{All: []v1beta1.SubscriptionsAPIFilter{
{Prefix: map[string]string{
"source": "foo"}},
{Suffix: map[string]string{
"subject": "test"}}}}}},
expectedOutput: "" +
"all: \n" +
" exact: \n" +
" type: foo.bar\n" +
" all: \n" +
" prefix: \n" +
" source: foo\n" +
" suffix: \n" +
" subject: test\n",
},
{
name: "Nested Any filter",
filter: v1beta1.SubscriptionsAPIFilter{
Any: []v1beta1.SubscriptionsAPIFilter{
{Exact: map[string]string{
"type": "foo.bar"}},
{Any: []v1beta1.SubscriptionsAPIFilter{
{Prefix: map[string]string{
"source": "foo"}},
{Suffix: map[string]string{
"subject": "test"}}}}}},
expectedOutput: "" +
"any: \n" +
" exact: \n" +
" type: foo.bar\n" +
" any: \n" +
" prefix: \n" +
" source: foo\n" +
" suffix: \n" +
" subject: test\n",
},
{
name: "Nested Not filter",
filter: v1beta1.SubscriptionsAPIFilter{
Not: &v1beta1.SubscriptionsAPIFilter{
Exact: map[string]string{
"type": "foo.bar",
},
Prefix: map[string]string{
"type": "bar",
},
CESQL: "select bar",
Not: &v1beta1.SubscriptionsAPIFilter{
Suffix: map[string]string{
"source": "foo"}}}},
expectedOutput: "" +
"not: \n" +
" not: \n" +
" suffix: \n" +
" source: foo\n" +
" exact: \n" +
" type: foo.bar\n" +
" prefix: \n" +
" type: bar\n" +
" cesql: select bar\n",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
buf := &bytes.Buffer{}
dw := printers.NewPrefixWriter(buf)
writeNestedFilters(dw, tc.filter)
err := dw.Flush()
assert.NilError(t, err)
assert.Equal(t, tc.expectedOutput, buf.String())
})
}
}
func getTriggerSinkRef() *v1beta1.Trigger { func getTriggerSinkRef() *v1beta1.Trigger {
return &v1beta1.Trigger{ return &v1beta1.Trigger{
TypeMeta: v1.TypeMeta{ TypeMeta: v1.TypeMeta{
@ -130,6 +286,9 @@ func getTriggerSinkRef() *v1beta1.Trigger {
"source": "src.eventing.knative", "source": "src.eventing.knative",
}, },
}, },
Filters: []v1beta1.SubscriptionsAPIFilter{
{CESQL: "LOWER(type) = 'my-event-type'"},
},
Subscriber: duckv1.Destination{ Subscriber: duckv1.Destination{
Ref: &duckv1.KReference{ Ref: &duckv1.KReference{
Kind: "Service", Kind: "Service",