Skip to content

Commit

Permalink
feat: custom trigger (#620)
Browse files Browse the repository at this point in the history
* feat: custom trigger

* chore: added debug log stmts.

* docs: custom trigger walkthrough

* docs: custom trigger walkthrough

* docs: custom trigger walkthrough

* docs: custom trigger walkthrough

* docs: custom trigger walkthrough
  • Loading branch information
VaibhavPage authored Apr 27, 2020
1 parent 6295610 commit cb1358d
Show file tree
Hide file tree
Showing 12 changed files with 252 additions and 40 deletions.
4 changes: 2 additions & 2 deletions api/event-source.html
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ <h3 id="argoproj.io/v1alpha1.EventSourceSpec">EventSourceSpec
<td>
<code>type</code></br>
<em>
github.com/argoproj/argo-events/pkg/apis/common.EventSourceType
Argo Events common.EventSourceType
</em>
</td>
<td>
Expand Down Expand Up @@ -2649,5 +2649,5 @@ <h3 id="argoproj.io/v1alpha1.TLSConfig">TLSConfig
<hr/>
<p><em>
Generated with <code>gen-crd-api-reference-docs</code>
on git commit <code>9f73feb</code>.
on git commit <code>2bedd9d</code>.
</em></p>
5 changes: 2 additions & 3 deletions api/event-source.md
Original file line number Diff line number Diff line change
Expand Up @@ -1491,8 +1491,7 @@ Generic event source

<td>

<code>type</code></br> <em>
github.com/argoproj/argo-events/pkg/apis/common.EventSourceType </em>
<code>type</code></br> <em> Argo Events common.EventSourceType </em>

</td>

Expand Down Expand Up @@ -5236,6 +5235,6 @@ ClientKeyPath refers the file path that contains client key.
<p>

<em> Generated with <code>gen-crd-api-reference-docs</code> on git
commit <code>9f73feb</code>. </em>
commit <code>2bedd9d</code>. </em>

</p>
6 changes: 3 additions & 3 deletions api/gateway.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ <h3 id="argoproj.io/v1alpha1.Gateway">Gateway
<td>
<code>type</code></br>
<em>
github.com/argoproj/argo-events/pkg/apis/common.EventSourceType
Argo Events common.EventSourceType
</em>
</td>
<td>
Expand Down Expand Up @@ -292,7 +292,7 @@ <h3 id="argoproj.io/v1alpha1.GatewaySpec">GatewaySpec
<td>
<code>type</code></br>
<em>
github.com/argoproj/argo-events/pkg/apis/common.EventSourceType
Argo Events common.EventSourceType
</em>
</td>
<td>
Expand Down Expand Up @@ -647,5 +647,5 @@ <h3 id="argoproj.io/v1alpha1.Subscribers">Subscribers
<hr/>
<p><em>
Generated with <code>gen-crd-api-reference-docs</code>
on git commit <code>9f73feb</code>.
on git commit <code>2bedd9d</code>.
</em></p>
8 changes: 3 additions & 5 deletions api/gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,7 @@ configurations for the gateway

<td>

<code>type</code></br> <em>
github.com/argoproj/argo-events/pkg/apis/common.EventSourceType </em>
<code>type</code></br> <em> Argo Events common.EventSourceType </em>

</td>

Expand Down Expand Up @@ -578,8 +577,7 @@ configurations for the gateway

<td>

<code>type</code></br> <em>
github.com/argoproj/argo-events/pkg/apis/common.EventSourceType </em>
<code>type</code></br> <em> Argo Events common.EventSourceType </em>

</td>

Expand Down Expand Up @@ -1277,6 +1275,6 @@ NATS refers to the subscribers over NATS protocol.
<p>

<em> Generated with <code>gen-crd-api-reference-docs</code> on git
commit <code>9f73feb</code>. </em>
commit <code>2bedd9d</code>. </em>

</p>
14 changes: 9 additions & 5 deletions api/sensor.html
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ <h3 id="argoproj.io/v1alpha1.ArtifactLocation">ArtifactLocation
<td>
<code>s3</code></br>
<em>
github.com/argoproj/argo-events/pkg/apis/common.S3Artifact
Argo Events common.S3Artifact
</em>
</td>
<td>
Expand Down Expand Up @@ -550,13 +550,17 @@ <h3 id="argoproj.io/v1alpha1.CustomTrigger">CustomTrigger
</tr>
<tr>
<td>
<code>triggerBody</code></br>
<code>spec</code></br>
<em>
string
map[string]string
</em>
</td>
<td>
<p>TriggerBody is the custom trigger resource specification that custom trigger gRPC server knows how to interpret.</p>
<p>Spec is the custom trigger resource specification that custom trigger gRPC server knows how to interpret.</p>
<br/>
<br/>
<table>
</table>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -3371,5 +3375,5 @@ <h3 id="argoproj.io/v1alpha1.URLArtifact">URLArtifact
<hr/>
<p><em>
Generated with <code>gen-crd-api-reference-docs</code>
on git commit <code>9f73feb</code>.
on git commit <code>2bedd9d</code>.
</em></p>
17 changes: 11 additions & 6 deletions api/sensor.md
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,7 @@ Description

<td>

<code>s3</code></br> <em>
github.com/argoproj/argo-events/pkg/apis/common.S3Artifact </em>
<code>s3</code></br> <em> Argo Events common.S3Artifact </em>

</td>

Expand Down Expand Up @@ -1132,19 +1131,25 @@ trigger gRPC server.

<td>

<code>triggerBody</code></br> <em> string </em>
<code>spec</code></br> <em> map\[string\]string </em>

</td>

<td>

<p>

TriggerBody is the custom trigger resource specification that custom
trigger gRPC server knows how to interpret.
Spec is the custom trigger resource specification that custom trigger
gRPC server knows how to interpret.

</p>

<br/> <br/>

<table>

</table>

</td>

</tr>
Expand Down Expand Up @@ -6699,6 +6704,6 @@ VerifyCert decides whether the connection is secure or not
<p>

<em> Generated with <code>gen-crd-api-reference-docs</code> on git
commit <code>9f73feb</code>. </em>
commit <code>2bedd9d</code>. </em>

</p>
2 changes: 1 addition & 1 deletion controllers/sensor/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ func validateCustomTrigger(trigger *v1alpha1.CustomTrigger) error {
if trigger.ServerURL == "" {
return errors.New("custom trigger gRPC server url is not defined")
}
if trigger.TriggerBody == "" {
if trigger.Spec == nil {
return errors.New("trigger body can't be empty")
}
if trigger.Secure {
Expand Down
112 changes: 112 additions & 0 deletions docs/triggers/build-your-own-trigger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Build Your Own Trigger

Argo Events supports a variety of triggers out of box like Argo Workflow, K8s Objects, AWS Lambda, HTTP Requests etc., but you may want to write your own logic to trigger a pipeline or create an object in K8s cluster. An example would be to trigger
TektonCD or AirFlow pipelines on GitHub events.

## Custom Trigger

In order to plug your own implementation for a trigger with Argo Events Sensor, you need to
run a gRPC server that implements the interface that the sensor expects.

### Interface

The interface exposed via proto file,

// Trigger offers services to build a custom trigger
service Trigger {
// FetchResource fetches the resource to be triggered.
rpc FetchResource(FetchResourceRequest) returns (FetchResourceResponse);
// Execute executes the requested trigger resource.
rpc Execute(ExecuteRequest) returns (ExecuteResponse);
// ApplyPolicy applies policies on the trigger execution result.
rpc ApplyPolicy(ApplyPolicyRequest) returns (ApplyPolicyResponse);
}

The complete proto file is available [here](https://github.com/argoproj/argo-events/blob/master/sensors/triggers/trigger.proto).

Let's walk through the contract,

1. `FetchResource`: If the trigger server needs to fetch a resource from external sources like S3, Git or a URL, this is the
place to do so. e.g. if the trigger server aims to invoke a TektonCD pipeline and the `PipelineRun` resource lives on Git, then
trigger server can first fetch it from Git and return it back to sensor.

2. `Execute`: In this method, the trigger server executes/invokes the trigger. e.g. TektonCD pipeline resource being
created in K8s cluster.

3. `ApplyPolicy`: This is where your trigger implementation can check whether the triggered resource transitioned into the success state.
Depending upon the response from the trigger server, the sensor will either stop processing subsequent triggers, or it will continue to
process them.


### How to define the Custom Trigger in a sensor?

Let's look at the following sensor,

apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
name: webhook-sensor
labels:
sensors.argoproj.io/sensor-controller-instanceid: argo-events
spec:
template:
spec:
containers:
- name: sensor
image: metalgearsolid/sensor:v0.15.0
imagePullPolicy: Always
serviceAccountName: argo-events-sa
dependencies:
- name: test-dep
gatewayName: webhook-gateway
eventName: example
subscription:
http:
port: 9300
triggers:
- template:
name: webhook-workflow-trigger
custom:
# the url of the trigger server.
serverURL: tekton-trigger.argo-events.svc:9000
# spec is map of string->string and it is sent over to trigger server.
# the spec can be anything you want as per your use-case, just make sure the trigger server understands the spec map.
spec:
url: "https://raw.githubusercontent.com/VaibhavPage/tekton-cd-trigger/master/example.yaml"
# These parameters are applied on resource fetched and returned by the trigger server.
# e.g. consider a trigger server which invokes TektonCD pipeline runs, then
# the trigger server can return a TektonCD PipelineRun resource.
# The parameters are then applied on that PipelineRun resource.
parameters:
- src:
dependencyName: test-dep
dataKey: body.namespace
dest: metadata.namespace
# These parameters are applied on entire template body.
# So that you can parameterize anything under `custom` key such as `serverURL`, `spec` etc.
parameters:
- src:
dependencyName: test-dep
dataKey: body.url
dest: custom.spec.url

The sensor definition should look familiar to you. The only difference is the `custom` key under `triggers -> template`.
The specification under `custom` key defines the custom trigger.

The most important fields are,

1. `serverURL`: This is the URL of the trigger gRPC server.

1. `spec`: It is a map of string -> string. The spec can be anything you want as per your use-case. The sensor sends
the spec to trigger server, and it is upto the trigger gRPC server to interpret the spec.

1. `parameters`: The parameters override the resource that is fetched by the trigger server.
Read more info on parameters [here](https://argoproj.github.io/argo-events/tutorials/02-parameterization/).

1. `payload`: Payload to send to the trigger server. Read more on payload [here](https://argoproj.github.io/argo-events/triggers/http-trigger/#request-payload).

The complete spec for the custom trigger is available [here](https://github.com/argoproj/argo-events/blob/master/api/sensor.md#customtrigger).

## Custom Trigger in Action

Refer to a sample [trigger server](https://github.com/VaibhavPage/tekton-cd-trigger) that invokes TektonCD pipeline on events.
47 changes: 47 additions & 0 deletions examples/sensors/custom-trigger.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
name: webhook-sensor
labels:
sensors.argoproj.io/sensor-controller-instanceid: argo-events
spec:
template:
spec:
containers:
- name: sensor
image: metalgearsolid/sensor:v0.15.0
imagePullPolicy: Always
serviceAccountName: argo-events-sa
dependencies:
- name: test-dep
gatewayName: webhook-gateway
eventName: example
subscription:
http:
port: 9300
triggers:
- template:
name: webhook-workflow-trigger
custom:
# the url of the trigger server.
serverURL: tekton-trigger.argo-events.svc:9000
# spec is map of string->string and it is sent over to trigger server.
# the spec can be anything you want as per your use-case, just make sure the trigger server understands the spec map.
spec:
url: "https://raw.githubusercontent.com/VaibhavPage/tekton-cd-trigger/master/example.yaml"
# These parameters are applied on resource fetched and returned by the trigger server.
# e.g. consider a trigger server which invokes TektonCD pipeline runs, then
# the trigger server can return a TektonCD PipelineRun resource.
# The parameters are then applied on that PipelineRun resource.
parameters:
- src:
dependencyName: test-dep
dataKey: body.namespace
dest: metadata.namespace
# These parameters are applied on entire template body.
# So that you can parameterize anything under `custom` key such as `serverURL`, `spec` etc.
parameters:
- src:
dependencyName: test-dep
dataKey: body.url
dest: custom.spec.url
4 changes: 2 additions & 2 deletions pkg/apis/sensor/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,8 +486,8 @@ type CustomTrigger struct {
CertFilePath string `json:"certFilePath,omitempty" protobuf:"bytes,3,opt,name=certFilePath"`
// ServerNameOverride for the secure connection between sensor and custom trigger gRPC server.
ServerNameOverride string `json:"serverNameOverride,omitempty" protobuf:"bytes,4,opt,name=serverNameOverride"`
// TriggerBody is the custom trigger resource specification that custom trigger gRPC server knows how to interpret.
TriggerBody string `json:"triggerBody" protobuf:"bytes,5,name=triggerBody"`
// Spec is the custom trigger resource specification that custom trigger gRPC server knows how to interpret.
Spec map[string]string `json:"spec" protobuf:"bytes,5,name=spec"`
// Parameters is the list of parameters that is applied to resolved custom trigger trigger object.
// +listType=triggerParameters
Parameters []TriggerParameter `json:"parameters,omitempty" protobuf:"bytes,6,rep,name=parameters"`
Expand Down
7 changes: 7 additions & 0 deletions pkg/apis/sensor/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit cb1358d

Please sign in to comment.