mirror of https://github.com/knative/client.git
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:
parent
7e90298d92
commit
e2513545b8
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue