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

Refactor template resolution into separate binding and template funcs. #226

Merged
merged 1 commit into from
Nov 20, 2019
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
33 changes: 19 additions & 14 deletions pkg/sink/sink.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,55 +78,60 @@ func (r Sink) HandleEvent(response http.ResponseWriter, request *http.Request) {
}

eventID := template.UID()
r.Logger.Debugf("EventListener: %s in Namespace: %s handling event (EventID: %s) with payload: %s and header: %v",
eventLog := r.Logger.With(zap.String(triggersv1.EventIDLabelKey, eventID))
eventLog.Debugf("EventListener: %s in Namespace: %s handling event (EventID: %s) with payload: %s and header: %v",
r.EventListenerName, r.EventListenerNamespace, eventID, string(event), request.Header)

result := make(chan int, 10)
// Execute each Trigger

for _, trigger := range el.Spec.Triggers {
t := trigger
for _, t := range el.Spec.Triggers {
log := eventLog.With(zap.String(triggersv1.TriggerLabelKey, t.Name))

var interceptor interceptors.Interceptor
if t.Interceptor != nil {
switch {
case t.Interceptor.Webhook != nil:
interceptor = webhook.NewInterceptor(t.Interceptor.Webhook, r.HTTPClient, r.EventListenerNamespace, r.Logger)
interceptor = webhook.NewInterceptor(t.Interceptor.Webhook, r.HTTPClient, r.EventListenerNamespace, log)
case t.Interceptor.Github != nil:
interceptor = github.NewInterceptor(t.Interceptor.Github, r.KubeClientSet, r.EventListenerNamespace, r.Logger)
interceptor = github.NewInterceptor(t.Interceptor.Github, r.KubeClientSet, r.EventListenerNamespace, log)
case t.Interceptor.Gitlab != nil:
interceptor = gitlab.NewInterceptor(t.Interceptor.Gitlab, r.KubeClientSet, r.EventListenerNamespace, r.Logger)
interceptor = gitlab.NewInterceptor(t.Interceptor.Gitlab, r.KubeClientSet, r.EventListenerNamespace, log)
}
}
go func() {
go func(t triggersv1.EventListenerTrigger) {
finalPayload := event
if interceptor != nil {
payload, err := interceptor.ExecuteTrigger(event, request, &t, eventID)
if err != nil {
r.Logger.Error(err)
log.Error(err)
result <- http.StatusAccepted
return
}
finalPayload = payload
}
binding, err := template.ResolveBinding(t,
rt, err := template.ResolveTrigger(t,
r.TriggersClient.TektonV1alpha1().TriggerBindings(r.EventListenerNamespace).Get,
r.TriggersClient.TektonV1alpha1().TriggerTemplates(r.EventListenerNamespace).Get)
if err != nil {
r.Logger.Error(err)
log.Error(err)
result <- http.StatusAccepted
return
}
resources, err := template.NewResources(finalPayload, request.Header, binding)

params, err := template.ResolveParams(rt.TriggerBindings, finalPayload, request.Header, rt.TriggerTemplate.Spec.Params)
if err != nil {
r.Logger.Error(err)
log.Error(err)
result <- http.StatusAccepted
return
}
log.Info("params: %+v", params)
resources := template.ResolveResources(rt.TriggerTemplate, params)
if err := r.createResources(resources, t.Name, eventID); err != nil {
r.Logger.Error(err)
log.Error(err)
}
result <- http.StatusCreated
}()
}(t)
}

//The eventlistener waits until all the trigger executions (up-to the creation of the resources) and
Expand Down
50 changes: 28 additions & 22 deletions pkg/template/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,22 @@ import (
"strings"

pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
triggersv1 "github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1"
"github.com/tidwall/gjson"
"golang.org/x/xerrors"
)

// bodyPathVarRegex determines valid body path variables
// The body regular expression allows for a subset of GJSON syntax, the mininum
// required to navigate through dictionaries, query arrays and support
// namespaced label names e.g. tekton.dev/eventlistener
var bodyPathVarRegex = regexp.MustCompile(`\$\(body(\.[[:alnum:]/_\-\.\\]+|\.#\([[:alnum:]=<>%!"\*_-]+\)#??)*\)`)
var (
// bodyPathVarRegex determines valid body path variables
// The body regular expression allows for a subset of GJSON syntax, the mininum
// required to navigate through dictionaries, query arrays and support
// namespaced label names e.g. tekton.dev/eventlistener
bodyPathVarRegex = regexp.MustCompile(`\$\(body(\.[[:alnum:]/_\-\.\\]+|\.#\([[:alnum:]=<>%!"\*_-]+\)#??)*\)`)

// The headers regular expression allows for simple navigation down a hierarchy
// of dictionaries
var headerVarRegex = regexp.MustCompile(`\$\(header(\.[[:alnum:]_\-]+)?\)`)
// The headers regular expression allows for simple navigation down a hierarchy
// of dictionaries
headerVarRegex = regexp.MustCompile(`\$\(header(\.[[:alnum:]_\-]+)?\)`)
)

// getBodyPathFromVar returns the body path given an body path variable
// $(body.my.path) -> my.path
Expand All @@ -54,6 +57,7 @@ func getHeaderFromVar(headerVar string) string {
if headerVar == "$(header)" {
return ""
}

return strings.TrimSuffix(strings.TrimPrefix(headerVar, "$(header."), ")")
}

Expand Down Expand Up @@ -160,29 +164,31 @@ func getHeaderValue(header map[string][]string, headerName string) (string, erro
return strings.Replace(headerValue, `"`, `\"`, -1), nil
}

// NewResources returns all resources defined when applying the event and
// elParams to the TriggerTemplate and TriggerBinding in the ResolvedBinding.
func NewResources(body []byte, header map[string][]string, binding ResolvedBinding) ([]json.RawMessage, error) {
params, err := MergeBindingParams(binding.TriggerBindings)
// ResolveParams takes a given trigger binding and produces the resulting
// resource params.
func ResolveParams(bindings []*triggersv1.TriggerBinding, body []byte, header map[string][]string, params []pipelinev1.ParamSpec) ([]pipelinev1.Param, error) {
out, err := MergeBindingParams(bindings)
if err != nil {
return []json.RawMessage{}, xerrors.Errorf("error merging TriggerBinding params: %v", err)
return nil, xerrors.Errorf("error merging trigger params: %v", err)
}
params, err = ApplyBodyToParams(body, params)
out, err = ApplyBodyToParams(body, out)
if err != nil {
return []json.RawMessage{}, xerrors.Errorf("Error applying body to TriggerBinding params: %s", err)
return nil, xerrors.Errorf("error applying body to trigger params: %s", err)
}
params, err = ApplyHeaderToParams(header, params)
out, err = ApplyHeaderToParams(header, out)
if err != nil {
return []json.RawMessage{}, xerrors.Errorf("Error applying header to TriggerBinding params: %s", err)
return nil, xerrors.Errorf("error applying header to trigger params: %s", err)
}

params = MergeInDefaultParams(params, binding.TriggerTemplate.Spec.Params)
return MergeInDefaultParams(out, params), nil
}

resources := make([]json.RawMessage, len(binding.TriggerTemplate.Spec.ResourceTemplates))
func ResolveResources(template *triggersv1.TriggerTemplate, params []pipelinev1.Param) []json.RawMessage {
resources := make([]json.RawMessage, len(template.Spec.ResourceTemplates))
uid := UID()
for i := range binding.TriggerTemplate.Spec.ResourceTemplates {
resources[i] = ApplyParamsToResourceTemplate(params, binding.TriggerTemplate.Spec.ResourceTemplates[i].RawMessage)
for i := range template.Spec.ResourceTemplates {
resources[i] = ApplyParamsToResourceTemplate(params, template.Spec.ResourceTemplates[i].RawMessage)
resources[i] = ApplyUIDToResourceTemplate(resources[i], uid)
}
return resources, nil
return resources
}
38 changes: 20 additions & 18 deletions pkg/template/event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ func Test_NewResources(t *testing.T) {
type args struct {
body []byte
header map[string][]string
binding ResolvedBinding
binding ResolvedTrigger
}
tests := []struct {
name string
Expand All @@ -672,7 +672,7 @@ func Test_NewResources(t *testing.T) {
args: args{
body: json.RawMessage{},
header: map[string][]string{},
binding: ResolvedBinding{
binding: ResolvedTrigger{
TriggerTemplate: bldr.TriggerTemplate("tt", "namespace"),
TriggerBindings: []*triggersv1.TriggerBinding{bldr.TriggerBinding("tb", "namespace")},
},
Expand All @@ -683,7 +683,7 @@ func Test_NewResources(t *testing.T) {
args: args{
body: json.RawMessage(`{"foo": "bar"}`),
header: map[string][]string{"one": {"1"}},
binding: ResolvedBinding{
binding: ResolvedTrigger{
TriggerTemplate: bldr.TriggerTemplate("tt", "namespace",
bldr.TriggerTemplateSpec(
bldr.TriggerTemplateParam("param1", "description", ""),
Expand All @@ -709,7 +709,7 @@ func Test_NewResources(t *testing.T) {
args: args{
body: json.RawMessage(`{"foo": "bar"}`),
header: map[string][]string{"one": {"1"}},
binding: ResolvedBinding{
binding: ResolvedTrigger{
TriggerTemplate: bldr.TriggerTemplate("tt", "namespace",
bldr.TriggerTemplateSpec(
bldr.TriggerTemplateParam("param1", "description", ""),
Expand Down Expand Up @@ -739,7 +739,7 @@ func Test_NewResources(t *testing.T) {
name: "one resource template with one uid",
args: args{
body: json.RawMessage(`{"foo": "bar"}`),
binding: ResolvedBinding{
binding: ResolvedTrigger{
TriggerTemplate: bldr.TriggerTemplate("tt", "namespace",
bldr.TriggerTemplateSpec(
bldr.TriggerTemplateParam("param1", "description", ""),
Expand All @@ -762,7 +762,7 @@ func Test_NewResources(t *testing.T) {
name: "one resource template with three uid",
args: args{
body: json.RawMessage(`{"foo": "bar"}`),
binding: ResolvedBinding{
binding: ResolvedTrigger{
TriggerTemplate: bldr.TriggerTemplate("tt", "namespace",
bldr.TriggerTemplateSpec(
bldr.TriggerTemplateParam("param1", "description", ""),
Expand All @@ -785,7 +785,7 @@ func Test_NewResources(t *testing.T) {
name: "multiple resource templates with multiple uid",
args: args{
body: json.RawMessage(`{"foo": "bar"}`),
binding: ResolvedBinding{
binding: ResolvedTrigger{
TriggerTemplate: bldr.TriggerTemplate("tt", "namespace",
bldr.TriggerTemplateSpec(
bldr.TriggerTemplateParam("param1", "description", ""),
Expand Down Expand Up @@ -814,7 +814,7 @@ func Test_NewResources(t *testing.T) {
args: args{
body: json.RawMessage(`{"foo": "bar"}`),
header: map[string][]string{"one": {"1"}},
binding: ResolvedBinding{
binding: ResolvedTrigger{
TriggerTemplate: bldr.TriggerTemplate("tt", "namespace",
bldr.TriggerTemplateSpec(
bldr.TriggerTemplateParam("param1", "description", ""),
Expand Down Expand Up @@ -845,12 +845,14 @@ func Test_NewResources(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
// This seeds Uid() to return 'cbhtc'
rand.Seed(0)
got, err := NewResources(tt.args.body, tt.args.header, tt.args.binding)
params, err := ResolveParams(tt.args.binding.TriggerBindings, tt.args.body, tt.args.header, tt.args.binding.TriggerTemplate.Spec.Params)
if err != nil {
t.Errorf("NewResources() returned unexpected error: %s", err)
} else if diff := cmp.Diff(tt.want, got); diff != "" {
t.Fatalf("ResolveParams() returned unexpected error: %s", err)
}
got := ResolveResources(tt.args.binding.TriggerTemplate, params)
if diff := cmp.Diff(tt.want, got); diff != "" {
stringDiff := cmp.Diff(convertJSONRawMessagesToString(tt.want), convertJSONRawMessagesToString(got))
t.Errorf("NewResources(): -want +got: %s", stringDiff)
t.Errorf("ResolveResources(): -want +got: %s", stringDiff)
}
})
}
Expand All @@ -870,12 +872,12 @@ func Test_NewResources_error(t *testing.T) {
body []byte
header map[string][]string
elParams []pipelinev1.Param
binding ResolvedBinding
binding ResolvedTrigger
}{
{
name: "bodypath not found in body",
body: json.RawMessage(`{"foo": "bar"}`),
binding: ResolvedBinding{
binding: ResolvedTrigger{
TriggerTemplate: bldr.TriggerTemplate("tt", "namespace",
bldr.TriggerTemplateSpec(
bldr.TriggerTemplateParam("param1", "description", ""),
Expand All @@ -894,7 +896,7 @@ func Test_NewResources_error(t *testing.T) {
name: "header not found in event",
body: json.RawMessage(`{"foo": "bar"}`),
header: map[string][]string{"One": {"one"}},
binding: ResolvedBinding{
binding: ResolvedTrigger{
TriggerTemplate: bldr.TriggerTemplate("tt", "namespace",
bldr.TriggerTemplateSpec(
bldr.TriggerTemplateParam("param1", "description", ""),
Expand All @@ -917,7 +919,7 @@ func Test_NewResources_error(t *testing.T) {
Value: pipelinev1.ArrayOrString{StringVal: "value1", Type: pipelinev1.ParamTypeString},
},
},
binding: ResolvedBinding{
binding: ResolvedTrigger{
TriggerTemplate: bldr.TriggerTemplate("tt", "namespace",
bldr.TriggerTemplateSpec(
bldr.TriggerTemplateParam("param1", "description", ""),
Expand All @@ -934,7 +936,7 @@ func Test_NewResources_error(t *testing.T) {
},
{
name: "conflicting bindings",
binding: ResolvedBinding{
binding: ResolvedTrigger{
TriggerTemplate: bldr.TriggerTemplate("tt", "namespace",
bldr.TriggerTemplateSpec(
bldr.TriggerTemplateParam("param1", "description", ""),
Expand All @@ -957,7 +959,7 @@ func Test_NewResources_error(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewResources(tt.body, tt.header, tt.binding)
got, err := ResolveParams(tt.binding.TriggerBindings, tt.body, tt.header, tt.binding.TriggerTemplate.Spec.Params)
if err == nil {
t.Errorf("NewResources() did not return error when expected; got: %s", got)
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/template/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ import (
// uidMatch determines the uid variable within the resource template
var uidMatch = []byte(`$(uid)`)

// ResolvedBinding contains the dereferenced TriggerBindings and
// ResolvedTrigger contains the dereferenced TriggerBindings and
// TriggerTemplate after resolving the k8s ObjectRef.
type ResolvedBinding struct {
type ResolvedTrigger struct {
TriggerBindings []*triggersv1.TriggerBinding
TriggerTemplate *triggersv1.TriggerTemplate
}
Expand All @@ -44,22 +44,22 @@ type getTriggerTemplate func(name string, options metav1.GetOptions) (*triggersv

// ResolveBindings takes in a trigger containing object refs to bindings and
// templates and resolves them to their underlying values.
func ResolveBinding(trigger triggersv1.EventListenerTrigger, getTB getTriggerBinding, getTT getTriggerTemplate) (ResolvedBinding, error) {
func ResolveTrigger(trigger triggersv1.EventListenerTrigger, getTB getTriggerBinding, getTT getTriggerTemplate) (ResolvedTrigger, error) {
tb := make([]*triggersv1.TriggerBinding, 0, len(trigger.Bindings))
for _, b := range trigger.Bindings {
tb2, err := getTB(b.Name, metav1.GetOptions{})
if err != nil {
return ResolvedBinding{}, xerrors.Errorf("error getting TriggerBinding %s: %s", b.Name, err)
return ResolvedTrigger{}, xerrors.Errorf("error getting TriggerBinding %s: %s", b.Name, err)
}
tb = append(tb, tb2)
}

ttName := trigger.Template.Name
tt, err := getTT(ttName, metav1.GetOptions{})
if err != nil {
return ResolvedBinding{}, xerrors.Errorf("Error getting TriggerTemplate %s: %s", ttName, err)
return ResolvedTrigger{}, xerrors.Errorf("Error getting TriggerTemplate %s: %s", ttName, err)
}
return ResolvedBinding{TriggerBindings: tb, TriggerTemplate: tt}, nil
return ResolvedTrigger{TriggerBindings: tb, TriggerTemplate: tt}, nil
}

// MergeInDefaultParams returns the params with the addition of all
Expand Down
Loading