diff --git a/docs/tutorials/02-parameterization.md b/docs/tutorials/02-parameterization.md index c0ccddb1f9..8c709ed49e 100644 --- a/docs/tutorials/02-parameterization.md +++ b/docs/tutorials/02-parameterization.md @@ -159,6 +159,91 @@ important when the `key` you defined in the parameter doesn't exist in the event \ \ __/ \____\______/ + +
+ +### Sprig Templates + +The [sprig template](https://github.com/Masterminds/sprig) exposed through `contextTemplate` and `dataTemplate` lets you alter the event +context and event data before it gets applied to the trigger via `parameters`. + +Take a look at the example defined [here](https://github.com/argoproj/argo-events/blob/master/examples/sensors/trigger-with-template.yaml), it contains the parameters +as follows, + + parameters: + # Retrieve the 'message' key from the payload + - src: + dependencyName: test-dep + dataTemplate: "{{ .Input.body.message | title }}" + dest: spec.arguments.parameters.0.value + # Title case the context subject + - src: + dependencyName: test-dep + contextTemplate: "{{ .Input.subject | title }}" + dest: spec.arguments.parameters.1.value + # Retrieve the 'name' key from the payload, remove all whitespace and lowercase it. + - src: + dependencyName: test-dep + dataTemplate: "{{ .Input.body.name | nospace | lower }}-" + dest: metadata.generateName + operation: append + + +Consider the event the sensor received has format like, + + { + "context": { + "type": "type_of_gateway", + "specVersion": "cloud_events_version", + "source": "name_of_the_gateway", + "eventID": "unique_event_id", + "time": "event_time", + "dataContentType": "type_of_data", + "subject": "name_of_the_event_within_event_source" + }, + "data": { + "body": { + "name": "foo bar", + "message": "hello there!!" + }, + } + } + +The parameters are transformed as, + +1. The first parameter extracts the `body.message` from event data and applies `title` filter which basically + capitalizes the first letter and replaces the `spec.arguments.parameters.0.value`. +1. The second parameter extracts the `subject` from the event context and again applies `title` filter and replaces the + `spec.arguments.parameters.1.value`. +1. The third parameter extracts the `body.name` from the event data, applies `nospace` filter which removes all + white spaces and then `lower` filter which lowercases the text and appends it to `metadata.generateName`. + +Send a curl request to webhook-gateway as follows, + + curl -d '{"name":"foo bar", "message": "hello there!!"}' -H "Content-Type: application/json" -X POST http://localhost:12000/example + +and you will an Argo workflow being sprung with name like `webhook-foobar-xxxxx`. + + +Check the output of workflow, it should print something like, + + ____________________________ + < Hello There!! from Example > + ---------------------------- + \ + \ + \ + ## . + ## ## ## == + ## ## ## ## === + /""""""""""""""""___/ === + ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~ + \______ o __/ + \ \ __/ + \____\______/ + +
+ ### Operations Sometimes you need the ability to append or prepend a parameter value to an existing value in trigger resource. This is where the `operation` field within @@ -195,6 +280,7 @@ a parameter comes handy. \ \ __/ \____\______/ + ## Trigger Template Parameterization The parameterization you saw above deals with the trigger resource, but sometimes you need to parameterize the trigger template itself. This comes handy when you have diff --git a/examples/sensors/trigger-with-template.yaml b/examples/sensors/trigger-with-template.yaml index 12d1585c1d..5290e73ce8 100644 --- a/examples/sensors/trigger-with-template.yaml +++ b/examples/sensors/trigger-with-template.yaml @@ -1,7 +1,7 @@ apiVersion: argoproj.io/v1alpha1 kind: Sensor metadata: - name: trigger-template + name: webhook-sensor labels: sensors.argoproj.io/sensor-controller-instanceid: argo-events spec: @@ -38,6 +38,7 @@ spec: arguments: parameters: - name: message + - name: subject templates: - name: whalesay serviceAccountName: argo-events-sa @@ -53,17 +54,16 @@ spec: # Retrieve the 'message' key from the payload - src: dependencyName: test-dep - dataTemplate: "{{ .Input.message }}" + dataTemplate: "{{ .Input.body.message | title }}" dest: spec.arguments.parameters.0.value # Title case the context subject - src: dependencyName: test-dep contextTemplate: "{{ .Input.subject | title }}" dest: spec.arguments.parameters.1.value - # You can also form arbitrary values that don't derive from the - # dependency input + # Retrieve the 'name' key from the payload, remove all whitespace and lowercase it. - src: dependencyName: test-dep - dataTemplate: "{{ now | unixEpoch }}-" + dataTemplate: "{{ .Input.body.name | nospace | lower }}-" dest: metadata.generateName operation: append diff --git a/pkg/apis/sensor/v1alpha1/types.go b/pkg/apis/sensor/v1alpha1/types.go index 96474e131d..1bd30a12ad 100644 --- a/pkg/apis/sensor/v1alpha1/types.go +++ b/pkg/apis/sensor/v1alpha1/types.go @@ -597,11 +597,11 @@ type TriggerParameterSource struct { // If a DataTemplate is provided with a DataKey, the template will be evaluated first and fallback to the DataKey. // The templating follows the standard go-template syntax as well as sprig's extra functions. // See https://pkg.go.dev/text/template and https://masterminds.github.io/sprig/ - DataTemplate string `json:"dataTemplate,omitempty" protobuf:"bytes,3,opt,name=dataTemplate"` + DataTemplate string `json:"dataTemplate,omitempty" protobuf:"bytes,4,opt,name=dataTemplate"` // Value is the default literal value to use for this parameter source // This is only used if the DataKey is invalid. // If the DataKey is invalid and this is not defined, this param source will produce an error. - Value *string `json:"value,omitempty" protobuf:"bytes,3,opt,name=value"` + Value *string `json:"value,omitempty" protobuf:"bytes,5,opt,name=value"` } // TriggerPolicy dictates the policy for the trigger retries