Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slack interceptor 1542 #1548

Merged
merged 2 commits into from
Apr 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,33 @@ help:
version:

@echo $(VERSION)

.PHONY: deploy_tekton
deploy_tekton: clean_tekton | ; $(info $(M) deploying tekton on local cluster …) @ ## Deploying tekton on local clustert
-kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
-ko apply -f config;
-ko apply -f config/interceptors;

.PHONY: clean_tekton
clean_tekton: | ; $(info $(M) deleteing tekton from local cluster …) @ ## Deleteing tekton on local clustert
-ko delete -f config/interceptors;
-ko delete -f config;


.PHONY:
test_e2e_examples: deploy_tekton
-kubectl delete -f https://github.com/knative/net-kourier/releases/download/knative-v1.6.0/kourier.yaml
sleep 60
./test/e2e-tests-examples.sh


.PHONY:
test_examples: # deploy_tekton
-kubectl delete -f https://github.com/knative/net-kourier/releases/download/knative-v1.6.0/kourier.yaml
./test/e2e-tests-examples.sh


.PHONY:
create_kind:
-kind delete cluster --name tekton6
kind create cluster --name tekton7
14 changes: 14 additions & 0 deletions config/interceptors/core-interceptors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ spec:
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: ClusterInterceptor
metadata:
name: slack
labels:
server/type: https
spec:
clientConfig:
service:
name: tekton-triggers-core-interceptors
namespace: tekton-pipelines
path: "slack"
port: 8443
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: ClusterInterceptor
metadata:
name: github
labels:
Expand Down
33 changes: 33 additions & 0 deletions docs/interceptors.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ weight: 5
- [Bitbucket `Interceptors`](#bitbucket-interceptors)
- [Bitbucket Server](#bitbucket-server)
- [Bitbucket Cloud](#bitbucket-cloud)
- [slack `Interceptors`](#slack-interceptors)
- [CEL `Interceptors`](#cel-interceptors)
- [Implementing custom `Interceptors`](#implementing-custom-interceptors)

Expand Down Expand Up @@ -474,6 +475,38 @@ spec:
ref: bitbucket-cloud-template
```

### Slack Interceptors
A Slack `Interceptor` allows you to extract fields from a slack slash command [payload](https://api.slack.com/interactivity/slash-commands#app_command_handling) which are sent in the http form-data section.
the `Interceptor` requests fields extracts the requested fields and appends them to the `extensions`.


```yaml
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: slack-listener
annotations:
tekton.dev/payload-validation: "false"
spec:
triggers:
- name: slack-trigger
interceptors:
- ref:
name: "slack"
kind: ClusterInterceptor
params:
- name: requestedFields
value:
- text
```
Note: payload-validation must be disabled by add adding the following annotation

```yaml
annotations:
tekton.dev/payload-validation: "false"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should update our payload validation to allow json and form/urlencoded content types and return invalid for anything else

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @khrm

```


### CEL Interceptors

A CEL `Interceptor` allows you to filter and modify the payloads of incoming events using
Expand Down
24 changes: 24 additions & 0 deletions docs/triggers-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4414,6 +4414,30 @@ string
</tr>
</tbody>
</table>
<h3 id="triggers.tekton.dev/v1beta1.SlackInterceptor">SlackInterceptor
</h3>
<div>
</div>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>requestedFields</code><br/>
<em>
[]string
</em>
</td>
<td>
</td>
</tr>
</tbody>
</table>
<h3 id="triggers.tekton.dev/v1beta1.Status">Status
</h3>
<p>
Expand Down
36 changes: 36 additions & 0 deletions examples/v1beta1/slack/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
## Slack slash command EventListener

Creates an EventListener that listens for Slack events.

### Try it out locally:

1. To create the slack trigger and all related resources, run:

```bash
kubectl apply -f .
```

1. Port forward:

```bash
kubectl port-forward service/el-slack-listener 8080
```

1. Test by sending the sample payload.

```bash
curl -v \
-H 'X-Slack-Signature: sha1=ba0cdc263b3492a74b601d240c27efe81c4720cb' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'token=EidhofDor5uIpqQ9RrtOVdnC&team_id=T04PK47eDS4&team_domain=demoworkspace-tid8978&channel_id=C04NETw4NBH&channel_name=sample-app&user_id=U04NVDwF7R8&&command=%2Fbuild&text=main+2222&api_app_id=A04NXU23L&is_enterprise_install=false&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%2FT04PK47EDS4%2F4863712501879%2FdOMNffCDfTjlSskBrmB1bOtR&trigger_id=4890883491553.4801143489888.910b8eaae200b381834de25310583f74' \
http://localhost:8080
```

The response status code should be `202 Accepted`


1. You should see a new TaskRun that got created:

```bash
kubectl get taskruns | grep slack-run-
```
5 changes: 5 additions & 0 deletions examples/v1beta1/slack/curl.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
curl -v \
-H 'X-Slack-Signature: sha1=ba0cdc263b3492a74b601d240c27efe81c4720cb' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'token=EidhofDor5uIpqQ9RrtOVdnC&team_id=T04PK47eDS4&team_domain=demoworkspace-tid8978&channel_id=C04NETw4NBH&channel_name=sample-app&user_id=U04NVDwF7R8&&command=%2Fbuild&text=main+2222&api_app_id=A04NXU23L&is_enterprise_install=false&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%2FT04PK47EDS4%2F4863712501879%2FdOMNffCDfTjlSskBrmB1bOtR&trigger_id=4890883491553.4801143489888.910b8eaae200b381834de25310583f74' \
http://localhost:8080
1 change: 1 addition & 0 deletions examples/v1beta1/slack/rbac.yaml
49 changes: 49 additions & 0 deletions examples/v1beta1/slack/slack-eventlistener-interceptor.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: slack-listener
annotations:
tekton.dev/payload-validation: "false"
spec:
serviceAccountName: tekton-triggers-example-sa
triggers:
- name: slack-trigger
interceptors:
- ref:
name: "slack"
kind: ClusterInterceptor
params:
- name: requestedFields
value:
- text
- ref:
name: cel
params:
- name: "overlays"
value:
- key: branch
expression: 'extensions.text[0].split(" ")[0]'
- key: image
expression: 'extensions.text[0].split(" ")[1]'
bindings:
- name: branch
value: $(extensions.branch)
- name: image
value: $(extensions.image)
template:
spec:
params:
- name: response
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
generateName: slack-run-
spec:
taskSpec:
steps:
- image: ubuntu
script: |
#! /bin/bash
echo "response of slack : $(tt.params.response)"
32 changes: 32 additions & 0 deletions pkg/apis/triggers/v1beta1/openapi_generated.go

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

7 changes: 7 additions & 0 deletions pkg/apis/triggers/v1beta1/trigger_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ type WebhookInterceptor struct {
Header []v1beta1.Param `json:"header,omitempty"`
}

type SlackInterceptor struct {
// the Requested fields to be extracted from data form

// +listType=atomic
RequestedFields []string `json:"requestedFields,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a mandatory field? or do we extract all fields by default if no requestedFields is specifed

Copy link
Contributor Author

@ilan-pinto ilan-pinto Mar 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We extract only the requested fields.
it wont do any work if nothing is specified

}

// BitbucketInterceptor provides a webhook to intercept and pre-process events
type BitbucketInterceptor struct {
SecretRef *SecretRef `json:"secretRef,omitempty"`
Expand Down
21 changes: 21 additions & 0 deletions pkg/apis/triggers/v1beta1/zz_generated.deepcopy.go

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

2 changes: 2 additions & 0 deletions pkg/interceptors/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/tektoncd/triggers/pkg/interceptors/cel"
"github.com/tektoncd/triggers/pkg/interceptors/github"
"github.com/tektoncd/triggers/pkg/interceptors/gitlab"
"github.com/tektoncd/triggers/pkg/interceptors/slack"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
Expand Down Expand Up @@ -62,6 +63,7 @@ func NewWithCoreInterceptors(sg interceptors.SecretGetter, logger *zap.SugaredLo
"cel": cel.NewInterceptor(sg),
"github": github.NewInterceptor(sg),
"gitlab": gitlab.NewInterceptor(sg),
"slack": slack.NewInterceptor(sg),
}

for k, v := range i {
Expand Down
Loading