Skip to content

Commit

Permalink
introduce authentication/authorization at the EventListenerTrigger le…
Browse files Browse the repository at this point in the history
…vel (with default back to existing EventListener level)
  • Loading branch information
gabemontero committed Feb 26, 2020
1 parent 7345759 commit ede030f
Show file tree
Hide file tree
Showing 13 changed files with 831 additions and 37 deletions.
1 change: 1 addition & 0 deletions cmd/eventlistenersink/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func main() {
EventListenerName: sinkArgs.ElName,
EventListenerNamespace: sinkArgs.ElNamespace,
Logger: logger,
Auth: sink.DefaultAuthOverride{},
}

// Listen and serve
Expand Down
4 changes: 2 additions & 2 deletions docs/clustertriggerbindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ designed to encourage reusability clusterwide. You can reference a
ClusterTriggerBinding in any EventListener in any namespace.

<!-- FILE: examples/clustertriggerbindings/clustertriggerbinding.yaml -->

```YAML
apiVersion: tekton.dev/v1alpha1
kind: ClusterTriggerBinding
Expand All @@ -22,14 +21,14 @@ spec:
value: $(header.Content-Type)
```


You can specify multiple ClusterTriggerBindings in a Trigger. You can use a
ClusterTriggerBinding in multiple Triggers.

In case of using a ClusterTriggerBinding, the `Binding` kind should be added.
The default kind is TriggerBinding which represents a namespaced TriggerBinding.

<!-- FILE: examples/eventlisteners/eventlistener-clustertriggerbinding.yaml -->

```YAML
---
apiVersion: tekton.dev/v1alpha1
Expand All @@ -48,3 +47,4 @@ spec:
template:
name: pipeline-template
```

85 changes: 55 additions & 30 deletions docs/eventlisteners.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Tekton resources. In addition, EventListeners allow lightweight event processing
using [Event Interceptors](#Interceptors).

- [Syntax](#syntax)
- [ServiceAccountName](#serviceAccountName)
- [Triggers](#triggers)
- [Interceptors](#Interceptors)
- [ServiceAccountName](#serviceAccountName)
- [Logging](#logging)
- [Labels](#labels)
- [Examples](#examples)
Expand Down Expand Up @@ -41,38 +41,13 @@ the following fields:
[kubernetes-overview]:
https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields

### Triggers

The `triggers` field is required. Each EventListener can consist of one or more
`triggers`. A Trigger consists of:

- `name` - (Optional) a valid
[Kubernetes name](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set)
- [`interceptors`](#interceptors) - (Optional) list of interceptors to use
- `bindings` - A list of names of `TriggerBindings` to use
- `template` - The name of `TriggerTemplate` to use

```yaml
triggers:
- name: trigger-1
interceptors:
- github:
eventTypes: ["pull_request"]
bindings:
- name: pipeline-binding
- name: message-binding
template:
name: pipeline-template
```

### ServiceAccountName

The `serviceAccountName` field is required. The ServiceAccount that the
EventListener sink uses to create the Tekton resources. The ServiceAccount needs
a role with the following rules:

<!-- FILE: examples/role-resources/triggerbinding-roles/role.yaml -->

```YAML
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
Expand All @@ -92,11 +67,61 @@ rules:
verbs: ["create"]
```


If your EventListener is using
[`ClusterTriggerBindings`](./clustertriggerbindings.md), you'll need a
ServiceAccount with a
[ClusterRole instead](../examples/role-resources/clustertriggerbinding-roles/clusterrole.yaml).

### Triggers

The `triggers` field is required. Each EventListener can consist of one or more
`triggers`. A Trigger consists of:

- `name` - (Optional) a valid
[Kubernetes name](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set)
- [`interceptors`](#interceptors) - (Optional) list of interceptors to use
- `bindings` - A list of names of `TriggerBindings` to use
- `template` - The name of `TriggerTemplate` to use

```yaml
triggers:
- name: trigger-1
interceptors:
- github:
eventTypes: ["pull_request"]
bindings:
- name: pipeline-binding
- name: message-binding
template:
name: pipeline-template
```

Also, to support multi-tenant styled scenarios, where an administrator may not want all triggers to have
the same permissions as the `EventListener`, a service account can optionally be set at the trigger level
and used if present in place of the `EventListener` service account when creating resources:

```yaml
triggers:
- name: trigger-1
serviceAccount:
name: trigger-1-sa
namespace: event-listener-namespace
interceptors:
- github:
eventTypes: ["pull_request"]
bindings:
- name: pipeline-binding
- name: message-binding
template:
name: pipeline-template
```

*NOTE*: When employing per trigger service accounts, if the specified service account resides in a namespace that differs
from the namespace of the `EventListener`, you'll need apply cluster level access for service accounts and secrets
to the `EventListener` service account. See the [example cluster trigger bindings](../examples/clustertriggerbindings)
for an illustration of how that is done.

### ServiceType

The `serviceType` field is optional. EventListener sinks are exposed via
Expand Down Expand Up @@ -199,7 +224,6 @@ if desired. The response body and headers of the last Interceptor is used for
resource binding/templating.

<!-- FILE: examples/eventlisteners/eventlistener-interceptor.yaml -->

```YAML
---
apiVersion: tekton.dev/v1alpha1
Expand Down Expand Up @@ -230,6 +254,7 @@ spec:
name: pipeline-template
```


### GitHub Interceptors

GitHub Interceptors contain logic to validate and filter webhooks that come from
Expand All @@ -251,7 +276,6 @@ The body/header of the incoming request will be preserved in this Interceptor's
response.

<!-- FILE: examples/eventlisteners/github-eventlistener-interceptor.yaml -->

```YAML
---
apiVersion: tekton.dev/v1alpha1
Expand All @@ -275,6 +299,7 @@ spec:
name: pipeline-template
```


### GitLab Interceptors

GitLab Interceptors contain logic to validate and filter requests that come from
Expand Down Expand Up @@ -334,7 +359,6 @@ The body/header of the incoming request will be preserved in this Interceptor's
response.

<!-- FILE: examples/eventlisteners/cel-eventlistener-interceptor.yaml -->

```YAML
apiVersion: tekton.dev/v1alpha1
kind: EventListener
Expand Down Expand Up @@ -364,12 +388,12 @@ spec:
name: pipeline-template
```


If no filter is provided, then the overlays will be applied to the body. With a
filter, the `expression` must return a `true` value, otherwise the request will
be filtered out.

<!-- FILE: examples/eventlisteners/cel-eventlistener-no-filter.yaml -->

```YAML
apiVersion: tekton.dev/v1alpha1
kind: EventListener
Expand All @@ -390,6 +414,7 @@ spec:
name: pipeline-template
```


## Examples

For complete examples, see
Expand Down
2 changes: 1 addition & 1 deletion docs/triggerbindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ parameters. The separation of `TriggerBinding`s from `TriggerTemplate`s was
deliberate to encourage reuse between them.

<!-- FILE: examples/triggerbindings/triggerbinding.yaml -->

```YAML
apiVersion: tekton.dev/v1alpha1
kind: TriggerBinding
Expand All @@ -22,6 +21,7 @@ spec:
value: $(header.Content-Type)
```


`TriggerBinding`s are connected to `TriggerTemplate`s within an
[`EventListener`](eventlisteners.md), which is where the pod is actually
instantiated that "listens" for the respective events.
Expand Down
2 changes: 1 addition & 1 deletion docs/triggertemplates.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ A `TriggerTemplate` is a resource that can template resources.
**anywhere** within the resource template.

<!-- FILE: examples/triggertemplates/triggertemplate.yaml -->

```YAML
apiVersion: tekton.dev/v1alpha1
kind: TriggerTemplate
Expand Down Expand Up @@ -47,6 +46,7 @@ spec:
value: $(params.gitrepositoryurl)
```


Similar to
[Pipelines](https://github.com/tektoncd/pipeline/blob/master/docs/pipelines.md),`TriggerTemplate`s
do not do any actual work, but instead act as the blueprint for what resources
Expand Down
9 changes: 9 additions & 0 deletions pkg/apis/triggers/v1alpha1/event_listener_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ type EventListenerTrigger struct {
// +optional
Name string `json:"name,omitempty"`
Interceptors []*EventInterceptor `json:"interceptors,omitempty"`
// ServiceAccount optionally associates credentials with each trigger;
// more granular authorization for
// who is allowed to utilize the associated pipeline
// vs. defaulting to whatever permissions are associated
// with the entire EventListener and associated sink facilitates
// multi-tenant model based scenarios
// TODO do we want to restrict this to the event listener namespace and just ask for the service account name here?
// +optional
ServiceAccount *corev1.ObjectReference `json:"serviceAccount,omitempty"`
}

// EventInterceptor provides a hook to intercept and pre-process events
Expand Down
5 changes: 5 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.

4 changes: 4 additions & 0 deletions pkg/resources/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package resources
import (
"encoding/json"
"fmt"
kerrors "k8s.io/apimachinery/pkg/api/errors"
"strings"

"k8s.io/client-go/dynamic"
Expand Down Expand Up @@ -99,6 +100,9 @@ func Create(logger *zap.SugaredLogger, rt json.RawMessage, triggerName, eventID,
logger.Infof("For event ID %q creating resource %v", eventID, gvr)

if _, err := dc.Resource(gvr).Namespace(namespace).Create(data, metav1.CreateOptions{}); err != nil {
if kerrors.IsUnauthorized(err) {
return err
}
return fmt.Errorf("couldn't create resource with group version kind %q: %v", gvr, err)
}
return nil
Expand Down
Loading

0 comments on commit ede030f

Please sign in to comment.