github.com/argoproj/argo-events@v1.9.1/docs/sensors/filters/data.md (about) 1 2 # Data Filter 3 4 Data filters are applied to the event data. A CloudEvent from Webhook event-source has payload structure as: 5 6 ```json 7 { 8 "context": { 9 "type": "type_of_event_source", 10 "specversion": "cloud_events_version", 11 "source": "name_of_the_event_source", 12 "id": "unique_event_id", 13 "time": "event_time", 14 "datacontenttype": "type_of_data", 15 "subject": "name_of_the_configuration_within_event_source" 16 }, 17 "data": { 18 "header": {}, 19 "body": {}, 20 } 21 } 22 ``` 23 24 Data filters are applied on `data` within the payload. 25 26 ## Fields 27 28 A data filter has following fields: 29 30 ```yaml 31 filters: 32 dataLogicalOperator: logical_operator_applied 33 data: 34 - path: path_within_event_data 35 type: types_of_the_data 36 comparator: numeric_comparator 37 value: 38 - list_of_possible_values 39 ``` 40 41 > ⚠️ `PLEASE NOTE` order in which data filters are declared corresponds to the order in which the Sensor will evaluate them. 42 43 ## Logical operator 44 45 Data filters can be evaluated together in 2 ways: 46 47 - `and`, meaning that all data filters returning `true` are required for an event to be valid 48 - `or`, meaning that only one data filter returning `true` is enough for an event to be valid 49 50 Any kind of error is considered as `false` (e.g. path not existing in event body). 51 52 Such behaviour can be configured with `dataLogicalOperator` field in a Sensor dependency filters, e.g. 53 54 ```yaml 55 apiVersion: argoproj.io/v1alpha1 56 kind: Sensor 57 metadata: 58 name: data-filters-example 59 spec: 60 dependencies: 61 - name: sample-dependency 62 eventSourceName: webhook 63 eventName: sample-event 64 filters: 65 dataLogicalOperator: "or" 66 data: 67 - path: "a" 68 type: "bool" 69 value: 70 - "true" 71 - path: "b.c" 72 type: "number" 73 value: 74 - "3.14" 75 - path: "b.d" 76 type: "string" 77 value: 78 - "hello there" 79 # ... 80 ``` 81 82 Available values: 83 84 - `""` (empty), defaulting to `and` 85 - `and`, default behaviour 86 - `or` 87 88 > ⚠️ `PLEASE NOTE` Data logical operator values must be `lower case`. 89 90 ## How it works 91 92 ### Comparator 93 94 The data filter offers following `comparators`: 95 96 - `>=` 97 - `>` 98 - `=` 99 - `!=` 100 - `<` 101 - `<=` 102 103 e.g. 104 105 ```yaml 106 filters: 107 data: 108 - path: body.value 109 type: number 110 comparator: ">" 111 value: 112 - "50.0" 113 ``` 114 115 **Note**: 116 117 - If data type is `string`, you can pass either an exact value or a regex. In any case that value will be evaluated as a regex. 118 - If data types is `bool` or `float`, you have to pass an exact value. 119 120 ### Multiple paths 121 122 If the HTTP request was less simple and contained multiple paths that you would like to filter against, you can use [multipaths](https://github.com/tidwall/gjson/blob/master/SYNTAX.md#multipaths) to combine multiple data paths in the payload into one string. 123 124 For a given payload such as: 125 126 ```json 127 { 128 "body": { 129 "action":"opened", 130 "labels": [ 131 {"id":"1234", "name":"Webhook"}, 132 {"id":"5678", "name":"Approved"} 133 ] 134 } 135 } 136 ``` 137 138 We want our sensor to fire if the action is "opened" and it has a label of "Webhook" or if the action is "closed" and it has a label of "Webhook" and "Approved". 139 140 The path would look like `body.action,body.labels.#(name=="Webhook").name,body.labels.#(name=="Approved").name` 141 142 This would return a string like: `"opened","Webhook"` or `"closed","Webhook","Approved"`.\ 143 144 As the resulting data type will be a `string`, we can pass a regex over it: 145 146 ```yaml 147 filters: 148 data: 149 - path: 'body.action,body.labels.#(name=="Webhook").name,body.labels.#(name=="Approved").name' 150 type: string 151 value: 152 - '"opened","Webhook"' 153 - '"closed","Webhook","Approved"' 154 ``` 155 156 ### Template 157 158 `template` process the incoming data defined in `path` through [sprig template](https://github.com/Masterminds/sprig) before matching with the `value`. 159 160 e.g. 161 162 ```yaml 163 filters: 164 data: 165 - path: body.message 166 type: string 167 value: 168 - "hello world" 169 template: "{{ b64dec .Input }}" 170 ``` 171 172 The message `'{"message":"aGVsbG8gd29ybGQ="}'` will match with the above filter definition. 173 174 **Note**: Data type is assumed to be string before applying the `template`, then cast to the user defined `type` for value matching. 175 176 ## Practical examples (comparator) 177 178 1. Create a webhook event-source 179 180 kubectl -n argo-events apply -f https://raw.githubusercontent.com/argoproj/argo-events/stable/examples/event-sources/webhook.yaml 181 182 1. Create a webhook sensor with data filter 183 184 kubectl -n argo-events apply -f https://raw.githubusercontent.com/argoproj/argo-events/stable/examples/sensors/filter-with-data-simple-1.yaml 185 186 1. Send an HTTP request to event-source 187 188 curl -d '{"message":"this is my first webhook"}' -H "Content-Type: application/json" -X POST http://localhost:12000/example 189 190 1. You will notice in sensor logs that the event is invalid as it expects for either `hello` or `hey` as the value of `body.message` 191 192 1. Send another HTTP request to event-source 193 194 curl -d '{"message":"hello"}' -H "Content-Type: application/json" -X POST http://localhost:12000/example 195 196 1. Look for a workflow with name starting with `data-workflow-` 197 198 ## Further examples 199 200 You can find some examples [here](https://github.com/argoproj/argo-events/tree/master/examples/sensors).