diff --git a/cmd/eventlistenersink/main.go b/cmd/eventlistenersink/main.go index 538c8701b7..ac0c320726 100644 --- a/cmd/eventlistenersink/main.go +++ b/cmd/eventlistenersink/main.go @@ -113,6 +113,7 @@ func main() { TriggerBindingLister: factory.Triggers().V1alpha1().TriggerBindings().Lister(), ClusterTriggerBindingLister: factory.Triggers().V1alpha1().ClusterTriggerBindings().Lister(), TriggerTemplateLister: factory.Triggers().V1alpha1().TriggerTemplates().Lister(), + InterceptorLister: factory.Triggers().V1alpha1().Interceptors().Lister(), } // Listen and serve diff --git a/config/core-interceptors.yaml b/config/core-interceptors.yaml new file mode 100644 index 0000000000..5f191c02bb --- /dev/null +++ b/config/core-interceptors.yaml @@ -0,0 +1,70 @@ +# Copyright 2020 The Tekton Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: triggers.tekton.dev/v1alpha1 +kind: Interceptor +metadata: + name: cel +spec: + clientConfig: + url: "http://tekton-triggers-core-interceptors.tekton-pipelines.svc/cel" + # Until #869 is implemented, the params field is only informational + params: + - name: "filter" + description: "A CEL expression that evaluates to true or false" + - name: "overlays" + description: "CEL expressions whose values get mapped to user defined keys" +--- +apiVersion: triggers.tekton.dev/v1alpha1 +kind: Interceptor +metadata: + name: bitbucket +spec: + clientConfig: + url: "http://tekton-triggers-core-interceptors.tekton-pipelines.svc/bitbucket" + # Until #869 is implemented, the params field is only informational + params: + - name: "eventTypes" + description: "A list of event types to accept" + - name: "secretRef" + description: "A reference to a secret containing a shared token for payload validation" +--- +apiVersion: triggers.tekton.dev/v1alpha1 +kind: Interceptor +metadata: + name: github +spec: + clientConfig: + url: "http://tekton-triggers-core-interceptors.tekton-pipelines.svc/github" + # Until #869 is implemented, the params field is only informational + params: + - name: "eventTypes" + description: "A list of event types to accept" + - name: "secretRef" + description: "A reference to a secret containing a shared token for payload validation" +--- +apiVersion: triggers.tekton.dev/v1alpha1 +kind: Interceptor +metadata: + name: gitlab +spec: + clientConfig: + url: "http://tekton-triggers-core-interceptors.tekton-pipelines.svc/gitlab" + # Until #869 is implemented, the params field is only informational + params: + - name: "eventTypes" + description: "A list of event types to accept" + - name: "secretRef" + description: "A reference to a secret containing a shared token for payload validation" +--- diff --git a/docs/interceptors.md b/docs/interceptors.md new file mode 100644 index 0000000000..fe57b70899 --- /dev/null +++ b/docs/interceptors.md @@ -0,0 +1,51 @@ + +# Interceptor + +A `Interceptor` is cluster scoped resource that can be invoked during the +processing of a trigger to modify the behavior or payload of Triggers. The +custom resource describes how an EventListener can connect to a workload that +is running the interceptor business logic (and in the future what extra +paramters the interceptor accepts). + +**NOTE**: This doc is a WIP. Please also see the [Interceptors section](./eventlisteners.md#interceptors) in the EventListener doc. + +- [Interceptors](#interceptors) + - [Syntax](#syntax) + -- [clientConfig](#clientConfig) + +## Syntax + +To define a configuration file for an `Interceptor` resource, you can specify +the following fields: + +- Required: + - [`apiVersion`][kubernetes-overview] - Specifies the API version, for example + `triggers.tekton.dev/v1alpha1`. + - [`kind`][kubernetes-overview] - Specifies the `Trigger` resource + object. + - [`metadata`][kubernetes-overview] - Specifies data to uniquely identify the + `Interceptor` resource object, for example a `name`. + - [`spec`][kubernetes-overview] - Specifies the configuration information for + your Interceptor resource object. The spec include: + - [`clientConfig`] - Specifies how a client (e.g. an EventListener) can communicate with the Interceptor. + +### clientConfig + +The `clientConfig` field describes how a client can communicate with an +interceptor. At the moment, it can contain only the `url` field whose value is +a resolvable URL. EventListeners will send forward requests to this URL. + +```yaml +spec: + clientConfig: + url: "http://interceptor-svc.default.svc/" +``` + +## Examples + +Triggers ships with a few built-in interceptors. These configurations can be found [`config/interceptors`](../config/interceptors). diff --git a/examples/rbac.yaml b/examples/rbac.yaml index 407b04a4e0..e1987d36b7 100644 --- a/examples/rbac.yaml +++ b/examples/rbac.yaml @@ -13,9 +13,8 @@ rules: resources: ["eventlisteners", "triggerbindings", "triggertemplates", "triggers"] verbs: ["get", "list", "watch"] - apiGroups: [""] - # secrets are only needed for GitHub/GitLab interceptors # configmaps is needed for updating logging config - resources: ["configmaps", "secrets"] + resources: ["configmaps"] verbs: ["get", "list", "watch"] # Permissions to create resources in associated TriggerTemplates - apiGroups: ["tekton.dev"] @@ -48,7 +47,7 @@ metadata: rules: # EventListeners need to be able to fetch any clustertriggerbindings - apiGroups: ["triggers.tekton.dev"] - resources: ["clustertriggerbindings"] + resources: ["clustertriggerbindings", "interceptors"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 diff --git a/pkg/interceptors/interceptors.go b/pkg/interceptors/interceptors.go index 7b4fce2d80..130c79b101 100644 --- a/pkg/interceptors/interceptors.go +++ b/pkg/interceptors/interceptors.go @@ -20,14 +20,14 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "io/ioutil" "net/http" - "net/url" - "os" "path" "google.golang.org/grpc/codes" + "knative.dev/pkg/apis" triggersv1 "github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -171,28 +171,40 @@ func UnmarshalParams(ip map[string]interface{}, p interface{}) error { return nil } -// ResolveURL returns the URL for the given core interceptor -func ResolveURL(i *triggersv1.TriggerInterceptor) *url.URL { +// Getname returns the name for the given core interceptor +func GetName(i *triggersv1.TriggerInterceptor) string { // This is temporary until we implement #868 - path := "" + name := "" switch { case i.Bitbucket != nil: - path = "bitbucket" + name = "bitbucket" case i.CEL != nil: - path = "cel" + name = "cel" case i.GitHub != nil: - path = "github" + name = "github" case i.GitLab != nil: - path = "gitlab" + name = "gitlab" } - return &url.URL{ - Scheme: "http", - Host: fmt.Sprintf("%s.%s.svc", CoreInterceptorsHost, os.Getenv("TEKTON_INSTALL_NAMESPACE")), - Path: path, + return name +} + +// Resolve resolves the given CEL name to the +type InterceptorGetter func(name string) (*triggersv1.Interceptor, error) + +var ErrNoURL = errors.New("interceptor URL was not found") + +func ResolveToURL(getter InterceptorGetter, name string) (*apis.URL, error) { + ic, err := getter(name) + if err != nil { + return nil, err + } + url := ic.Spec.ClientConfig.URL + if url == nil { + return nil, ErrNoURL } + return ic.Spec.ClientConfig.URL, nil } -// Execute executes the InterceptorRequest using the given httpClient func Execute(ctx context.Context, client *http.Client, req *triggersv1.InterceptorRequest, url string) (*triggersv1.InterceptorResponse, error) { b, err := json.Marshal(req) if err != nil { diff --git a/pkg/interceptors/interceptors_test.go b/pkg/interceptors/interceptors_test.go index d8870a86d8..ee032a980a 100644 --- a/pkg/interceptors/interceptors_test.go +++ b/pkg/interceptors/interceptors_test.go @@ -18,11 +18,11 @@ package interceptors_test import ( "context" + "errors" "fmt" "net/http" "net/http/httptest" "net/url" - "os" "strings" "testing" @@ -35,6 +35,7 @@ import ( "google.golang.org/grpc/codes" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/apis" fakekubeclient "knative.dev/pkg/client/injection/kube/client/fake" rtesting "knative.dev/pkg/reconciler/testing" ) @@ -305,48 +306,76 @@ func TestResolvePath(t *testing.T) { in: triggersv1.EventInterceptor{ CEL: &triggersv1.CELInterceptor{}, }, - want: "http://tekton-triggers-core-interceptors.tekton-pipelines.svc/cel", + want: "cel", }, { in: triggersv1.EventInterceptor{ GitLab: &triggersv1.GitLabInterceptor{}, }, - want: "http://tekton-triggers-core-interceptors.tekton-pipelines.svc/gitlab", + want: "gitlab", }, { in: triggersv1.EventInterceptor{ GitHub: &triggersv1.GitHubInterceptor{}, }, - want: "http://tekton-triggers-core-interceptors.tekton-pipelines.svc/github", + want: "github", }, { in: triggersv1.EventInterceptor{ Bitbucket: &triggersv1.BitbucketInterceptor{}, }, - want: "http://tekton-triggers-core-interceptors.tekton-pipelines.svc/bitbucket", + want: "bitbucket", }, { in: triggersv1.EventInterceptor{ Webhook: &triggersv1.WebhookInterceptor{}, }, - want: "http://tekton-triggers-core-interceptors.tekton-pipelines.svc", + want: "", }} { t.Run(tc.want, func(t *testing.T) { - os.Setenv("TEKTON_INSTALL_NAMESPACE", "tekton-pipelines") - t.Cleanup(func() { os.Unsetenv("TEKTON_INSTALL_NAMESPACE") }) - got := interceptors.ResolveURL(&tc.in) - if tc.want != got.String() { + got := interceptors.GetName(&tc.in) + if tc.want != got { t.Fatalf("ResolveURL() want: %s; got: %s", tc.want, got) } }) } +} - t.Run("different namespaces", func(t *testing.T) { - os.Setenv("TEKTON_INSTALL_NAMESPACE", "another-namespace") - t.Cleanup(func() { os.Unsetenv("TEKTON_INSTALL_NAMESPACE") }) - in := &triggersv1.EventInterceptor{ - Bitbucket: &triggersv1.BitbucketInterceptor{}, +func TestResolveToURL(t *testing.T) { + t.Run("resolves URL", func(t *testing.T) { + fakeGetter := func(n string) (*triggersv1.Interceptor, error) { + return &triggersv1.Interceptor{ + Spec: triggersv1.InterceptorSpec{ + ClientConfig: triggersv1.ClientConfig{ + URL: &apis.URL{ + Scheme: "http", + Host: "some-host", + Path: n, + }, + }, + }, + }, nil + } + + got, err := interceptors.ResolveToURL(fakeGetter, "cel") + if err != nil { + t.Fatalf("ResolveToURL() error: %s", err) + } + want := "http://some-host/cel" + if got.String() != want { + t.Fatalf("ResolveToURL want: %s; got: %s", want, got.String()) + } + }) + + t.Run("interceptor has no URL", func(t *testing.T) { + fakeGetter := func(name string) (*triggersv1.Interceptor, error) { + return &triggersv1.Interceptor{ + Spec: triggersv1.InterceptorSpec{ + ClientConfig: triggersv1.ClientConfig{ + URL: nil, + }, + }, + }, nil } - got := interceptors.ResolveURL(in) - want := "http://tekton-triggers-core-interceptors.another-namespace.svc/bitbucket" - if want != got.String() { - t.Fatalf("ResolveURL() want: %s; got: %s", want, got) + _, err := interceptors.ResolveToURL(fakeGetter, "cel") + if !errors.Is(err, interceptors.ErrNoURL) { + t.Fatalf("ResolveToURL expected error to be %s but got %s", interceptors.ErrNoURL, err) } }) } diff --git a/pkg/reconciler/v1alpha1/eventlistener/eventlistener.go b/pkg/reconciler/v1alpha1/eventlistener/eventlistener.go index daa25a4e7a..451b5b271a 100644 --- a/pkg/reconciler/v1alpha1/eventlistener/eventlistener.go +++ b/pkg/reconciler/v1alpha1/eventlistener/eventlistener.go @@ -26,7 +26,6 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" "github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1" listers "github.com/tektoncd/triggers/pkg/client/listers/triggers/v1alpha1" - "github.com/tektoncd/triggers/pkg/system" "go.uber.org/zap" "golang.org/x/xerrors" appsv1 "k8s.io/api/apps/v1" @@ -463,9 +462,6 @@ func getContainer(el *v1alpha1.EventListener, c Config) corev1.Container { FieldPath: "metadata.namespace", }, }, - }, { - Name: "TEKTON_INSTALL_NAMESPACE", - Value: system.GetNamespace(), }} certEnv := map[string]*corev1.EnvVarSource{} diff --git a/pkg/reconciler/v1alpha1/eventlistener/eventlistener_test.go b/pkg/reconciler/v1alpha1/eventlistener/eventlistener_test.go index 3d2863b8d7..56e1e4c592 100644 --- a/pkg/reconciler/v1alpha1/eventlistener/eventlistener_test.go +++ b/pkg/reconciler/v1alpha1/eventlistener/eventlistener_test.go @@ -248,9 +248,6 @@ func makeDeployment(ops ...func(d *appsv1.Deployment)) *appsv1.Deployment { FieldPath: "metadata.namespace", }, }, - }, { - Name: "TEKTON_INSTALL_NAMESPACE", - Value: "tekton-pipelines", }}, }}, Volumes: []corev1.Volume{{ @@ -336,9 +333,6 @@ var withTLSConfig = func(d *appsv1.Deployment) { FieldPath: "metadata.namespace", }, }, - }, { - Name: "TEKTON_INSTALL_NAMESPACE", - Value: "tekton-pipelines", }, { Name: "TLS_CERT", ValueFrom: &corev1.EnvVarSource{ diff --git a/pkg/sink/sink.go b/pkg/sink/sink.go index cf9a481ef5..657d7eb52e 100644 --- a/pkg/sink/sink.go +++ b/pkg/sink/sink.go @@ -61,6 +61,7 @@ type Sink struct { TriggerBindingLister listers.TriggerBindingLister ClusterTriggerBindingLister listers.ClusterTriggerBindingLister TriggerTemplateLister listers.TriggerTemplateLister + InterceptorLister listers.InterceptorLister } // Response defines the HTTP body that the Sink responds to events with. @@ -116,6 +117,8 @@ func (r Sink) HandleEvent(response http.ResponseWriter, request *http.Request) { triggers, err := r.merge(el.Spec.Triggers, trItems) if err != nil { r.Logger.Errorf("Error merging Triggers: %s", err) + response.WriteHeader(http.StatusInternalServerError) + return } result := make(chan int, 10) // Execute each Trigger @@ -290,9 +293,14 @@ func (r Sink) ExecuteInterceptors(t triggersv1.Trigger, in *http.Request, event request.Body = string(payload) continue } - // TODO: Plumb through context from EL request.InterceptorParams = interceptors.GetInterceptorParams(i) - interceptorResponse, err := interceptors.Execute(context.Background(), r.HTTPClient, &request, interceptors.ResolveURL(i).String()) + url, err := interceptors.ResolveToURL(r.InterceptorLister.Get, interceptors.GetName(i)) + if err != nil { + return nil, nil, nil, fmt.Errorf("could not resolve interceptor URL: %w", err) + } + + // TODO: Plumb through context from EL + interceptorResponse, err := interceptors.Execute(context.Background(), r.HTTPClient, &request, url.String()) if err != nil { return nil, nil, nil, err } diff --git a/pkg/sink/sink_test.go b/pkg/sink/sink_test.go index a7fcf05ae6..3dcee82ede 100644 --- a/pkg/sink/sink_test.go +++ b/pkg/sink/sink_test.go @@ -40,6 +40,7 @@ import ( "github.com/tektoncd/triggers/pkg/client/dynamic/clientset/tekton" clustertriggerbindinginformer "github.com/tektoncd/triggers/pkg/client/injection/informers/triggers/v1alpha1/clustertriggerbinding" eventlistenerinformer "github.com/tektoncd/triggers/pkg/client/injection/informers/triggers/v1alpha1/eventlistener" + interceptorinformer "github.com/tektoncd/triggers/pkg/client/injection/informers/triggers/v1alpha1/interceptor" triggerinformer "github.com/tektoncd/triggers/pkg/client/injection/informers/triggers/v1alpha1/trigger" triggerbindinginformer "github.com/tektoncd/triggers/pkg/client/injection/informers/triggers/v1alpha1/triggerbinding" triggertemplateinformer "github.com/tektoncd/triggers/pkg/client/injection/informers/triggers/v1alpha1/triggertemplate" @@ -61,6 +62,7 @@ import ( fakedynamic "k8s.io/client-go/dynamic/fake" "k8s.io/client-go/kubernetes" ktesting "k8s.io/client-go/testing" + "knative.dev/pkg/apis" "knative.dev/pkg/ptr" rtesting "knative.dev/pkg/reconciler/testing" ) @@ -75,6 +77,51 @@ func init() { template.UID = func() string { return eventID } } +var ( + github = &triggersv1.Interceptor{ + ObjectMeta: metav1.ObjectMeta{ + Name: "github", + }, + Spec: triggersv1.InterceptorSpec{ + ClientConfig: triggersv1.ClientConfig{ + URL: &apis.URL{ + Scheme: "http", + Host: "tekton-triggers-core-interceptors", + Path: "/github", + }, + }, + }, + } + cel = &triggersv1.Interceptor{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cel", + }, + Spec: triggersv1.InterceptorSpec{ + ClientConfig: triggersv1.ClientConfig{ + URL: &apis.URL{ + Scheme: "http", + Host: "tekton-triggers-core-interceptors", + Path: "/cel", + }, + }, + }, + } + bitbucket = &triggersv1.Interceptor{ + ObjectMeta: metav1.ObjectMeta{ + Name: "bitbucket", + }, + Spec: triggersv1.InterceptorSpec{ + ClientConfig: triggersv1.ClientConfig{ + URL: &apis.URL{ + Scheme: "http", + Host: "tekton-triggers-core-interceptors", + Path: "/bitbucket", + }, + }, + }, + } +) + // getSinkAssets seeds test resources and returns a testable Sink and a dynamic client. The returned client is used to // create the fake resources and can be used to check if the correct resources were created. func getSinkAssets(t *testing.T, resources test.Resources, elName string, webhookInterceptor http.Handler) (Sink, *fakedynamic.FakeDynamicClient) { @@ -105,6 +152,7 @@ func getSinkAssets(t *testing.T, resources test.Resources, elName string, webhoo TriggerBindingLister: triggerbindinginformer.Get(ctx).Lister(), ClusterTriggerBindingLister: clustertriggerbindinginformer.Get(ctx).Lister(), TriggerTemplateLister: triggertemplateinformer.Get(ctx).Lister(), + InterceptorLister: interceptorinformer.Get(ctx).Lister(), } return r, dynamicClient } @@ -480,6 +528,7 @@ func TestHandleEvent(t *testing.T) { "secretKey": []byte("secret"), }, }}, + Interceptors: []*triggersv1.Interceptor{github, cel}, Triggers: []*triggersv1.Trigger{{ ObjectMeta: metav1.ObjectMeta{ Name: "git-clone-trigger", @@ -536,6 +585,7 @@ func TestHandleEvent(t *testing.T) { "secretKey": []byte("secret"), }, }}, + Interceptors: []*triggersv1.Interceptor{bitbucket}, Triggers: []*triggersv1.Trigger{{ ObjectMeta: metav1.ObjectMeta{ Name: "git-clone-trigger", @@ -840,8 +890,8 @@ func TestHandleEvent_AuthOverride(t *testing.T) { "secretKey": []byte("secret"), }, } - resources := test.Resources{ + Interceptors: []*triggersv1.Interceptor{github}, Triggers: []*triggersv1.Trigger{trigger}, EventListeners: []*triggersv1.EventListener{el}, Secrets: []*corev1.Secret{secret, authSecret}, @@ -1105,7 +1155,10 @@ func TestExecuteInterceptor_error(t *testing.T) { } func TestExecuteInterceptor_NotContinue(t *testing.T) { - s, _ := getSinkAssets(t, test.Resources{}, "el-name", nil) + resources := test.Resources{ + Interceptors: []*triggersv1.Interceptor{cel}, + } + s, _ := getSinkAssets(t, resources, "el-name", nil) trigger := triggersv1.Trigger{ Spec: triggersv1.TriggerSpec{ Interceptors: []*triggersv1.EventInterceptor{{ @@ -1149,17 +1202,12 @@ func (f *echoInterceptor) ServeHTTP(w http.ResponseWriter, r *http.Request) { } func TestExecuteInterceptor_ExtensionChaining(t *testing.T) { - ctx, _ := rtesting.SetupFakeContext(t) - clients := test.SeedResources(t, ctx, test.Resources{}) - logger := zaptest.NewLogger(t).Sugar() - webhookInterceptorName := "foo" echoServer := &echoInterceptor{} - httpClient := setupInterceptors(t, clients.Kube, logger, echoServer) - s := Sink{ - HTTPClient: httpClient, - Logger: logger, + resources := test.Resources{ + Interceptors: []*triggersv1.Interceptor{cel}, } + s, _ := getSinkAssets(t, resources, "", echoServer) sha := "abcdefghi" // Fake "sha" to send via body // trigger has a chain of 3 interceptors CEL(overlay) -> webhook -> CEL(filter) @@ -1193,7 +1241,7 @@ func TestExecuteInterceptor_ExtensionChaining(t *testing.T) { t.Fatalf("http.NewRequest: %v", err) } body := fmt.Sprintf(`{"sha": "%s"}`, sha) - resp, _, iresp, err := s.ExecuteInterceptors(trigger, req, []byte(body), logger, eventID) + resp, _, iresp, err := s.ExecuteInterceptors(trigger, req, []byte(body), s.Logger, eventID) if err != nil { t.Fatalf("executeInterceptors: %v", err) } diff --git a/test/controller.go b/test/controller.go index af93ccd7e2..1027e252ce 100644 --- a/test/controller.go +++ b/test/controller.go @@ -32,6 +32,7 @@ import ( faketriggersclient "github.com/tektoncd/triggers/pkg/client/injection/client/fake" fakeclustertriggerbindinginformer "github.com/tektoncd/triggers/pkg/client/injection/informers/triggers/v1alpha1/clustertriggerbinding/fake" fakeeventlistenerinformer "github.com/tektoncd/triggers/pkg/client/injection/informers/triggers/v1alpha1/eventlistener/fake" + fakeinterceptorinformer "github.com/tektoncd/triggers/pkg/client/injection/informers/triggers/v1alpha1/interceptor/fake" faketriggerinformer "github.com/tektoncd/triggers/pkg/client/injection/informers/triggers/v1alpha1/trigger/fake" faketriggerbindinginformer "github.com/tektoncd/triggers/pkg/client/injection/informers/triggers/v1alpha1/triggerbinding/fake" faketriggertemplateinformer "github.com/tektoncd/triggers/pkg/client/injection/informers/triggers/v1alpha1/triggertemplate/fake" @@ -57,6 +58,7 @@ type Resources struct { Namespaces []*corev1.Namespace ClusterTriggerBindings []*v1alpha1.ClusterTriggerBinding EventListeners []*v1alpha1.EventListener + Interceptors []*v1alpha1.Interceptor TriggerBindings []*v1alpha1.TriggerBinding TriggerTemplates []*v1alpha1.TriggerTemplate Triggers []*v1alpha1.Trigger @@ -102,6 +104,7 @@ func SeedResources(t *testing.T, ctx context.Context, r Resources) Clients { // Setup fake informer for reconciler tests ctbInformer := fakeclustertriggerbindinginformer.Get(ctx) elInformer := fakeeventlistenerinformer.Get(ctx) + icInformer := fakeinterceptorinformer.Get(ctx) ttInformer := faketriggertemplateinformer.Get(ctx) tbInformer := faketriggerbindinginformer.Get(ctx) trInformer := faketriggerinformer.Get(ctx) @@ -135,6 +138,14 @@ func SeedResources(t *testing.T, ctx context.Context, r Resources) Clients { t.Fatal(err) } } + for _, ic := range r.Interceptors { + if err := icInformer.Informer().GetIndexer().Add(ic); err != nil { + t.Fatal(err) + } + if _, err := c.Triggers.TriggersV1alpha1().Interceptors().Create(context.Background(), ic, metav1.CreateOptions{}); err != nil { + t.Fatal(err) + } + } for _, tb := range r.TriggerBindings { if err := tbInformer.Informer().GetIndexer().Add(tb); err != nil { t.Fatal(err) diff --git a/test/eventlistener_test.go b/test/eventlistener_test.go index 3f677cbb7f..df80dc190d 100644 --- a/test/eventlistener_test.go +++ b/test/eventlistener_test.go @@ -243,7 +243,7 @@ func TestEventListenerCreate(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "my-role"}, Rules: []rbacv1.PolicyRule{{ APIGroups: []string{triggersv1.GroupName}, - Resources: []string{"clustertriggerbindings", "eventlisteners", "triggerbindings", "triggertemplates", "triggers"}, + Resources: []string{"clustertriggerbindings", "eventlisteners", "interceptors", "triggerbindings", "triggertemplates", "triggers"}, Verbs: []string{"get", "list", "watch"}, }, { APIGroups: []string{"tekton.dev"},