Skip to content

Commit

Permalink
Add BitBucket Interceptor with examples and README
Browse files Browse the repository at this point in the history
  • Loading branch information
savitaashture authored and tekton-robot committed Jun 3, 2020
1 parent d030a5b commit dd1aff6
Show file tree
Hide file tree
Showing 20 changed files with 748 additions and 53 deletions.
43 changes: 43 additions & 0 deletions docs/eventlisteners.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ Event Interceptors can take several different forms today:
- [Webhook Interceptors](#Webhook-Interceptors)
- [GitHub Interceptors](#GitHub-Interceptors)
- [GitLab Interceptors](#GitLab-Interceptors)
- [Bitbucket Interceptors](#Bitbucket-Interceptors)
- [CEL Interceptors](#CEL-Interceptors)

### Webhook Interceptors
Expand Down Expand Up @@ -417,6 +418,48 @@ spec:
name: pipeline-template
```

### Bitbucket Interceptors

Bitbucket Interceptors contain logic to validate and filter webhooks that come from
Bitbucket server or cloud. Supported features include validating webhooks actually came from Bitbucket as well as
filtering incoming events.

To use this Interceptor as a validator, create a secret string using the method
of your choice, and configure the Bitbucket webhook to use that secret value.
Create a Kubernetes secret containing this value, and pass that as a reference
to the `bitbucket` Interceptor.

To use this Interceptor as a filter, add the event types you would like to
accept to the `eventTypes` field. Valid values can be found in Bitbucket
[docs](https://confluence.atlassian.com/bitbucketserver/event-payload-938025882.html).

The body/header of the incoming request will be preserved in this Interceptor's
response.

<!-- FILE: examples/bitbucket/bitbucket-eventlistener-interceptor.yaml -->
```YAML
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
name: bitbucket-listener
spec:
serviceAccountName: tekton-triggers-bitbucket-sa
triggers:
- name: bitbucket-triggers
interceptors:
- bitbucket:
secretRef:
secretName: bitbucket-secret
secretKey: secretToken
eventTypes:
- repo:refs_changed
bindings:
- name: bitbucket-binding
template:
name: bitbucket-template
```

### CEL Interceptors

CEL Interceptors can be used to filter or modify incoming events, using the
Expand Down
45 changes: 45 additions & 0 deletions examples/bitbucket/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
## Bitbucket EventListener

Creates an EventListener that listens for Bitbucket webhook events.

### Try it out locally:

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

```bash
kubectl apply -f examples/bitbucket/
```

1. Port forward:

```bash
kubectl port-forward \
"$(kubectl get pod --selector=eventlistener=bitbucket-listener -oname)" \
8080
```

**Note**: Instead of port forwarding, you can set the
[`serviceType`](https://github.com/tektoncd/triggers/blob/master/docs/eventlisteners.md#serviceType)
to `LoadBalancer` to expose the EventListener with a public IP.

1. Test by sending the sample payload.

```bash
curl -v \
-H 'X-Event-Key: repo:refs_changed' \
-H 'X-Hub-Signature: sha1=c401e56873be567c1403d8504763760a39236c51' \
-d '{"repository": {"links": {"clone": [{"href": "ssh://git@localhost:7999/~test/helloworld.git", "name": "ssh"}, {"href": "http://localhost:7990/scm/~test/helloworld.git", "name": "http"}]}}, "changes": [{"ref": {"displayId": "master"}}]}' \
http://localhost:8080
```

The response status code should be `201 Created`

[`HMAC`](https://www.freeformatter.com/hmac-generator.html) tool used to create X-Hub-Signature.

In [`HMAC`](https://www.freeformatter.com/hmac-generator.html) `string` is the *body payload* and `secretKey` is the *given secretToken*.

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

```bash
kubectl get taskruns | grep bitbucket-run-
```
20 changes: 20 additions & 0 deletions examples/bitbucket/bitbucket-eventlistener-interceptor.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
name: bitbucket-listener
spec:
serviceAccountName: tekton-triggers-bitbucket-sa
triggers:
- name: bitbucket-triggers
interceptors:
- bitbucket:
secretRef:
secretName: bitbucket-secret
secretKey: secretToken
eventTypes:
- repo:refs_changed
bindings:
- name: bitbucket-binding
template:
name: bitbucket-template
36 changes: 36 additions & 0 deletions examples/bitbucket/role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-triggers-bitbucket-sa
secrets:
- name: bitbucket-secret
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tekton-triggers-bitbucket-minimal
rules:
# Permissions for every EventListener deployment to function
- apiGroups: ["triggers.tekton.dev"]
resources: ["eventlisteners", "triggerbindings", "triggertemplates"]
verbs: ["get"]
- apiGroups: [""]
# secrets are only needed for Github/Gitlab interceptors, serviceaccounts only for per trigger authorization
resources: ["configmaps", "secrets", "serviceaccounts"]
verbs: ["get", "list", "watch"]
# Permissions to create resources in associated TriggerTemplates
- apiGroups: ["tekton.dev"]
resources: ["pipelineruns", "pipelineresources", "taskruns"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: tekton-triggers-bitbucket-binding
subjects:
- kind: ServiceAccount
name: tekton-triggers-bitbucket-sa
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: tekton-triggers-bitbucket-minimal
7 changes: 7 additions & 0 deletions examples/bitbucket/secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: bitbucket-secret
type: Opaque
stringData:
secretToken: "1234567"
11 changes: 11 additions & 0 deletions examples/bitbucket/triggerbinding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
name: bitbucket-binding
spec:
params:
- name: gitrevision
value: $(body.changes[0].ref.displayId)
- name: gitrepositoryurl
value: $(body.repository.links.clone[1].href)
35 changes: 35 additions & 0 deletions examples/bitbucket/triggertemplate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
name: bitbucket-template
spec:
params:
- name: gitrevision
- name: gitrepositoryurl
resourcetemplates:
- apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
generateName: bitbucket-run-
spec:
taskSpec:
inputs:
resources:
- name: source
type: git
steps:
- image: ubuntu
script: |
#! /bin/bash
ls -al $(inputs.resources.source.path)
inputs:
resources:
- name: source
resourceSpec:
type: git
params:
- name: revision
value: $(params.gitrevision)
- name: url
value: $(params.gitrepositoryurl)
15 changes: 11 additions & 4 deletions pkg/apis/triggers/v1alpha1/event_listener_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,11 @@ type EventListenerTrigger struct {

// EventInterceptor provides a hook to intercept and pre-process events
type EventInterceptor struct {
Webhook *WebhookInterceptor `json:"webhook,omitempty"`
GitHub *GitHubInterceptor `json:"github,omitempty"`
GitLab *GitLabInterceptor `json:"gitlab,omitempty"`
CEL *CELInterceptor `json:"cel,omitempty"`
Webhook *WebhookInterceptor `json:"webhook,omitempty"`
GitHub *GitHubInterceptor `json:"github,omitempty"`
GitLab *GitLabInterceptor `json:"gitlab,omitempty"`
CEL *CELInterceptor `json:"cel,omitempty"`
Bitbucket *BitBucketInterceptor `json:"bitbucket,omitempty"`
}

// WebhookInterceptor provides a webhook to intercept and pre-process events
Expand All @@ -99,6 +100,12 @@ type WebhookInterceptor struct {
Header []v1beta1.Param `json:"header,omitempty"`
}

// BitBucketInterceptor provides a webhook to intercept and pre-process events
type BitBucketInterceptor struct {
SecretRef *SecretRef `json:"secretRef,omitempty"`
EventTypes []string `json:"eventTypes,omitempty"`
}

// GitHubInterceptor provides a webhook to intercept and pre-process events
type GitHubInterceptor struct {
SecretRef *SecretRef `json:"secretRef,omitempty"`
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/triggers/v1alpha1/event_listener_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ func TestSetDeploymentConditions(t *testing.T) {
if !equality.Semantic.DeepEqual(tests[i].expectedStatus, tests[i].initialStatus) {
t.Error("SetDeploymentConditions() equality mismatch. Ignore semantic time mismatch")
diff := cmp.Diff(tests[i].expectedStatus, tests[i].initialStatus)
t.Errorf("Diff request body: -want +got: %s", diff)
t.Errorf("Diff request body (-want +got) = %s", diff)
}
})
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/apis/triggers/v1alpha1/event_listener_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (t *EventListenerTrigger) validate(ctx context.Context) *apis.FieldError {
}

func (i *EventInterceptor) validate(ctx context.Context) *apis.FieldError {
if i.Webhook == nil && i.GitHub == nil && i.GitLab == nil && i.CEL == nil {
if i.Webhook == nil && i.GitHub == nil && i.GitLab == nil && i.CEL == nil && i.Bitbucket == nil {
return apis.ErrMissingField("interceptor")
}

Expand All @@ -101,6 +101,9 @@ func (i *EventInterceptor) validate(ctx context.Context) *apis.FieldError {
if i.GitLab != nil {
numSet++
}
if i.Bitbucket != nil {
numSet++
}

if numSet > 1 {
return apis.ErrMultipleOneOf("interceptor.webhook", "interceptor.github", "interceptor.gitlab")
Expand Down
5 changes: 3 additions & 2 deletions pkg/apis/triggers/v1alpha1/event_listener_validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,9 @@ func TestEventListenerValidate_error(t *testing.T) {
Bindings: []*v1alpha1.EventListenerBinding{{Name: "tb", Kind: v1alpha1.NamespacedTriggerBindingKind, Ref: "tb"}},
Template: v1alpha1.EventListenerTemplate{Name: "tt"},
Interceptors: []*v1alpha1.EventInterceptor{{
GitHub: &v1alpha1.GitHubInterceptor{},
GitLab: &v1alpha1.GitLabInterceptor{},
GitHub: &v1alpha1.GitHubInterceptor{},
GitLab: &v1alpha1.GitLabInterceptor{},
Bitbucket: &v1alpha1.BitBucketInterceptor{},
}},
}},
},
Expand Down
31 changes: 31 additions & 0 deletions pkg/apis/triggers/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 dd1aff6

Please sign in to comment.