Skip to content

Commit

Permalink
Implement CE Subscriptions filters
Browse files Browse the repository at this point in the history
Signed-off-by: Ahmed Abdalla <aabdelre@redhat.com>
  • Loading branch information
devguyio committed Sep 7, 2021
1 parent 4a55e51 commit cf97e31
Show file tree
Hide file tree
Showing 15 changed files with 946 additions and 162 deletions.
40 changes: 40 additions & 0 deletions config/core/resources/trigger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,46 @@ spec:
description: 'Attributes filters events by exact match on event context attributes. Each key in the map is compared with the equivalent key in the event context. An event passes the filter if all values are equal to the specified values. Nested context attributes are not supported as keys. Only string values are supported. '
type: object
x-kubernetes-preserve-unknown-fields: true
filters:
description: 'Filters is the filter to apply against all events from the Broker. Only events that pass this filter will be sent to the Subscriber. If not specified, will default to allowing all events. '
type: object
properties:
exact:
description: 'Exact evaluates to true if the value of the matching CloudEvents attribute is matches exactly the String value specified (case sensitive). Exact must contain exactly one property, where the key is the name of the CloudEvents attribute to be matched, and its value is the String value to use in the comparison. The attribute name and value specified in the filter express cannot be be empty strings.'
type: object
x-kubernetes-preserve-unknown-fields: true
prefix:
description: 'Prefix evaluates to true if the value of the matching CloudEvents attribute starts with the String value specified (case sensitive). Prefix must contain exactly one property, where the key is the name of the CloudEvents attribute to be matched, and its value is the String value to use in the comparison. The attribute name and value specified in the filter express cannot be be empty strings.'
type: object
x-kubernetes-preserve-unknown-fields: true
suffix:
description: 'Suffix evaluates to true if the value of the matching CloudEvents attribute ends with the String value specified (case sensitive). | Suffix must contain exactly one property, where the key is the name of the CloudEvents attribute to be matched, and its value is the String value to use in the comparison. he attribute name and value specified in the filter express cannot be be empty strings.'
type: object
x-kubernetes-preserve-unknown-fields: true
not:
description: 'Not evaluates to true if the nested expression evaluates to false.'
type: object
# Because kube doesn't allow to use $ref, we can't recursively define this schema.
x-kubernetes-preserve-unknown-fields: true
all:
description: 'All evaluates to true if all the nested expressions evaluate to true. All must contain at least one filter expression.'
type: array
items:
# Because kube doesn't allow to use $ref, we can't recursively reference to the filter schema.
type: object
description: "Sub schema"
x-kubernetes-preserve-unknown-fields: true
any:
description: 'Any evaluates to true if at least one of the nested expressions evaluate to true. Any must contain at least one filter expression.'
type: array
items:
# Because kube doesn't allow to use $ref, we can't recursively reference to the filter schema.
type: object
description: "Sub schema"
x-kubernetes-preserve-unknown-fields: true
# This allows extension filter dialects
additionalProperties: true
x-kubernetes-preserve-unknown-fields: true
subscriber:
description: Subscriber is the addressable that receives events from the Broker that pass the Filter. It is required.
type: object
Expand Down
240 changes: 212 additions & 28 deletions docs/eventing-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1564,8 +1564,8 @@ string
<td>
<code>filter</code><br/>
<em>
<a href="#eventing.knative.dev/v1.TriggerFilter">
TriggerFilter
<a href="#eventing.knative.dev/v1.AttributesFilter">
AttributesFilter
</a>
</em>
</td>
Expand All @@ -1577,6 +1577,29 @@ filter will be sent to the Subscriber. If not specified, will default to allowin
</tr>
<tr>
<td>
<code>filters</code><br/>
<em>
<a href="#eventing.knative.dev/v1.SubscriptionsAPIFiltersList">
SubscriptionsAPIFiltersList
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Filters is an experimental field that conforms to CNCF CloudEvents Subscriptions
API. It&rsquo;s An array of filter expressions that evaluates to true or false.
If any filter expression in the array evaluates to false, the event MUST
NOT be sent to the Subscriber. If all the filter expressions in the array
evaluates to true, the event MUST be attempted to be delivered. Absence of
a filter or empty array implies a value of true. In the event of users
specifying both Filter and Filters, then the later will override the first.
This will allow our users to try out the effect of the new filters field
without compromising existing Filter objects and try it out on existing
Trigger objects.</p>
</td>
</tr>
<tr>
<td>
<code>subscriber</code><br/>
<em>
<a href="https://pkg.go.dev/knative.dev/pkg/apis/duck/v1#Destination">
Expand All @@ -1585,8 +1608,8 @@ knative.dev/pkg/apis/duck/v1.Destination
</em>
</td>
<td>
<p>Subscriber is the addressable that receives events from the Broker that pass the Filter. It
is required.</p>
<p>Subscriber is the addressable that receives events from the Broker that pass
the Filter. It is required.</p>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -1623,6 +1646,45 @@ date.</p>
</tr>
</tbody>
</table>
<h3 id="eventing.knative.dev/v1.AttributesFilter">AttributesFilter
</h3>
<p>
(<em>Appears on:</em><a href="#eventing.knative.dev/v1.TriggerSpec">TriggerSpec</a>)
</p>
<p>
<p>AttributesFilter allows to define a filter expression. If multiple filters
are specified, then the same semantics of AttributesFilter.All is applied.
If no filter dialect or empty object is specified, then the filter always
accept the events.</p>
</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>attributes</code><br/>
<em>
<a href="#eventing.knative.dev/v1.CloudEventsAttributes">
CloudEventsAttributes
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Attributes filters events by exact match on event context attributes.
Each key in the map is compared with the equivalent key in the event
context. An event passes the filter if all values are equal to the
specified values. Nested context attributes are not supported as keys. Only
string values are supported.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="eventing.knative.dev/v1.BrokerSpec">BrokerSpec
</h3>
<p>
Expand Down Expand Up @@ -1723,12 +1785,26 @@ delivered into the Broker mesh.</p>
</tr>
</tbody>
</table>
<h3 id="eventing.knative.dev/v1.TriggerFilter">TriggerFilter
<h3 id="eventing.knative.dev/v1.CloudEventsAttributes">CloudEventsAttributes
(<code>map[string]string</code> alias)</p></h3>
<p>
(<em>Appears on:</em><a href="#eventing.knative.dev/v1.AttributesFilter">AttributesFilter</a>)
</p>
<p>
<p>CloudEventsAttributes is a map of context attribute names to values for
filtering by equality. Only exact matches will pass the filter. You can use
the value &ldquo; to indicate all strings match.</p>
</p>
<h3 id="eventing.knative.dev/v1.SubscriptionsAPIFilter">SubscriptionsAPIFilter
</h3>
<p>
(<em>Appears on:</em><a href="#eventing.knative.dev/v1.TriggerSpec">TriggerSpec</a>)
(<em>Appears on:</em><a href="#eventing.knative.dev/v1.SubscriptionsAPIFilter">SubscriptionsAPIFilter</a>)
</p>
<p>
<p>SubscriptionsAPIFilter allows defining a filter expression using CloudEvents
Subscriptions API. If multiple filters are specified, then the same semantics
of SubscriptionsAPIFilter.All is applied. If no filter dialect or empty
object is specified, then the filter always accept the events.</p>
</p>
<table>
<thead>
Expand All @@ -1740,34 +1816,119 @@ delivered into the Broker mesh.</p>
<tbody>
<tr>
<td>
<code>attributes</code><br/>
<code>all</code><br/>
<em>
<a href="#eventing.knative.dev/v1.TriggerFilterAttributes">
TriggerFilterAttributes
<a href="#eventing.knative.dev/v1.SubscriptionsAPIFiltersList">
SubscriptionsAPIFiltersList
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Attributes filters events by exact match on event context attributes.
Each key in the map is compared with the equivalent key in the event
context. An event passes the filter if all values are equal to the
specified values.</p>
<p>Nested context attributes are not supported as keys. Only string values are supported.</p>
<p>All evaluates to true if all the nested expressions evaluate to true.
It must contain at least one filter expression.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="eventing.knative.dev/v1.TriggerFilterAttributes">TriggerFilterAttributes
(<code>map[string]string</code> alias)</p></h3>
<p>
(<em>Appears on:</em><a href="#eventing.knative.dev/v1.TriggerFilter">TriggerFilter</a>)
</p>
<tr>
<td>
<code>any</code><br/>
<em>
<a href="#eventing.knative.dev/v1.SubscriptionsAPIFiltersList">
SubscriptionsAPIFiltersList
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Any evaluates to true if at least one of the nested expressions evaluates
to true. It must contain at least one filter expression.</p>
</td>
</tr>
<tr>
<td>
<code>not</code><br/>
<em>
<a href="#eventing.knative.dev/v1.SubscriptionsAPIFilter">
SubscriptionsAPIFilter
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Not evaluates to true if the nested expression evaluates to false.</p>
</td>
</tr>
<tr>
<td>
<code>exact</code><br/>
<em>
map[string]string
</em>
</td>
<td>
<em>(Optional)</em>
<p>Exact evaluates to true if the value of the matching CloudEvents
attribute matches exactly the String value specified (case-sensitive).
Exact must contain exactly one property, where the key is the name of the
CloudEvents attribute to be matched, and its value is the String value to
use in the comparison. The attribute name and value specified in the filter
expression cannot be empty strings.</p>
</td>
</tr>
<tr>
<td>
<code>prefix</code><br/>
<em>
map[string]string
</em>
</td>
<td>
<em>(Optional)</em>
<p>Prefix evaluates to true if the value of the matching CloudEvents
attribute starts with the String value specified (case-sensitive). Prefix
must contain exactly one property, where the key is the name of the
CloudEvents attribute to be matched, and its value is the String value to
use in the comparison. The attribute name and value specified in the filter
expression cannot be empty strings.</p>
</td>
</tr>
<tr>
<td>
<code>suffix</code><br/>
<em>
map[string]string
</em>
</td>
<td>
<em>(Optional)</em>
<p>Suffix evaluates to true if the value of the matching CloudEvents
attribute ends with the String value specified (case-sensitive). Suffix
must contain exactly one property, where the key is the name of the
CloudEvents attribute to be matched, and its value is the String value to
use in the comparison. The attribute name and value specified in the filter
expression cannot be empty strings.</p>
</td>
</tr>
<tr>
<td>
<code>Extensions</code><br/>
<em>
map[string]*k8s.io/apimachinery/pkg/runtime.RawExtension
</em>
</td>
<td>
<p>
<p>TriggerFilterAttributes is a map of context attribute names to values for
filtering by equality. Only exact matches will pass the filter. You can use the value &ldquo;
to indicate all strings match.</p>
(Members of <code>Extensions</code> are embedded into this type.)
</p>
<em>(Optional)</em>
<p>Extensions includes the list of additional filter dialects supported by
specific broker implementations. Check out the documentation of the
broker implementation you&rsquo;re using to know about what additional filters
are supported.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="eventing.knative.dev/v1.TriggerSpec">TriggerSpec
</h3>
<p>
Expand Down Expand Up @@ -1798,8 +1959,8 @@ string
<td>
<code>filter</code><br/>
<em>
<a href="#eventing.knative.dev/v1.TriggerFilter">
TriggerFilter
<a href="#eventing.knative.dev/v1.AttributesFilter">
AttributesFilter
</a>
</em>
</td>
Expand All @@ -1811,6 +1972,29 @@ filter will be sent to the Subscriber. If not specified, will default to allowin
</tr>
<tr>
<td>
<code>filters</code><br/>
<em>
<a href="#eventing.knative.dev/v1.SubscriptionsAPIFiltersList">
SubscriptionsAPIFiltersList
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Filters is an experimental field that conforms to CNCF CloudEvents Subscriptions
API. It&rsquo;s An array of filter expressions that evaluates to true or false.
If any filter expression in the array evaluates to false, the event MUST
NOT be sent to the Subscriber. If all the filter expressions in the array
evaluates to true, the event MUST be attempted to be delivered. Absence of
a filter or empty array implies a value of true. In the event of users
specifying both Filter and Filters, then the later will override the first.
This will allow our users to try out the effect of the new filters field
without compromising existing Filter objects and try it out on existing
Trigger objects.</p>
</td>
</tr>
<tr>
<td>
<code>subscriber</code><br/>
<em>
<a href="https://pkg.go.dev/knative.dev/pkg/apis/duck/v1#Destination">
Expand All @@ -1819,8 +2003,8 @@ knative.dev/pkg/apis/duck/v1.Destination
</em>
</td>
<td>
<p>Subscriber is the addressable that receives events from the Broker that pass the Filter. It
is required.</p>
<p>Subscriber is the addressable that receives events from the Broker that pass
the Filter. It is required.</p>
</td>
</tr>
<tr>
Expand Down
5 changes: 4 additions & 1 deletion pkg/apis/eventing/v1/trigger_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ func (t *Trigger) SetDefaults(ctx context.Context) {
func (ts *TriggerSpec) SetDefaults(ctx context.Context) {
// Make a default filter that allows anything.
if ts.Filter == nil {
ts.Filter = &TriggerFilter{}
ts.Filter = &AttributesFilter{
Attributes: &CloudEventsAttributes{},
}
}

// Default the Subscriber namespace
ts.Subscriber.SetDefaults(ctx)
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/apis/eventing/v1/trigger_defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ var (
defaultBroker = "default"
otherBroker = "other_broker"
namespace = "testnamespace"
emptyTriggerFilter = &TriggerFilter{}
defaultTrigger = Trigger{Spec: TriggerSpec{Filter: emptyTriggerFilter}}
emptyTriggerFilter = &AttributesFilter{
Attributes: &CloudEventsAttributes{},
}
defaultTrigger = Trigger{Spec: TriggerSpec{Filter: emptyTriggerFilter}}
)

func TestTriggerDefaults(t *testing.T) {
Expand Down
Loading

0 comments on commit cf97e31

Please sign in to comment.