Skip to content

Commit

Permalink
WIP Add support for more cloud events
Browse files Browse the repository at this point in the history
Change the event type string for taskruns from dev.tekton.event.task.*
to dev.tekton.event.taskrun.*. Since cloud events are only sent by
pipeline resources - which are alpha - we don't need to comply with
the beta deprecation policy for this.

Extend the cloudevents module to include more event types for TaskRuns
and event types for PipelineRuns, with unit test coverage.

At this stage there is no event producer that generates these new
events. This is preparing the stage for the next changes where
we will start to emit cloud events in addition to the k8s events
we emit today.
  • Loading branch information
afrittoli committed May 22, 2020
1 parent fc24674 commit 17d8b41
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 14 deletions.
2 changes: 1 addition & 1 deletion pkg/reconciler/events/cloudevent/cloud_event_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func SendCloudEvents(tr *v1beta1.TaskRun, ceclient CEClient, logger *zap.Sugared
logger = logger.With(zap.String("taskrun", tr.Name))

// Make the event we would like to send:
event, err := EventForTaskRun(tr)
event, err := EventForTaskRun(tr, nil)
if err != nil || event == nil {
logger.With(zap.Error(err)).Error("failed to produce a cloudevent from TaskRun.")
return err
Expand Down
57 changes: 45 additions & 12 deletions pkg/reconciler/events/cloudevent/cloudevent.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,39 @@ import (
"knative.dev/pkg/apis"

"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
"github.com/tektoncd/pipeline/pkg/reconciler/events"
)

// TektonEventType holds the types of cloud events sent by Tekton
type TektonEventType string

const (
// TektonTaskRunStartedV1 is sent for TaskRuns with "ConditionSucceeded" "Unknown"
// the first time they are picked up by the reconciler
TektonTaskRunStartedV1 TektonEventType = "dev.tekton.event.taskrun.started.v1"
// TektonTaskRunRunningV1 is sent for TaskRuns with "ConditionSucceeded" "Unknown"
// once the TaskRun is validated and Pod created
TektonTaskRunRunningV1 TektonEventType = "dev.tekton.event.taskrun.running.v1"
// TektonTaskRunUnknownV1 is sent for TaskRuns with "ConditionSucceeded" "Unknown"
TektonTaskRunUnknownV1 TektonEventType = "dev.tekton.event.task.unknown.v1"
// It can be used as a confirmation that the TaskRun is still running.
TektonTaskRunUnknownV1 TektonEventType = "dev.tekton.event.taskrun.unknown.v1"
// TektonTaskRunSuccessfulV1 is sent for TaskRuns with "ConditionSucceeded" "True"
TektonTaskRunSuccessfulV1 TektonEventType = "dev.tekton.event.task.successful.v1"
TektonTaskRunSuccessfulV1 TektonEventType = "dev.tekton.event.taskrun.successful.v1"
// TektonTaskRunFailedV1 is sent for TaskRuns with "ConditionSucceeded" "False"
TektonTaskRunFailedV1 TektonEventType = "dev.tekton.event.task.failed.v1"
TektonTaskRunFailedV1 TektonEventType = "dev.tekton.event.taskrun.failed.v1"
// TektonPipelineRunStartedV1 is sent for PipelineRuns with "ConditionSucceeded" "Unknown"
// the first time they are picked up by the reconciler
TektonPipelineRunStartedV1 TektonEventType = "dev.tekton.event.pipelinerun.started.v1"
// TektonPipelineRunRunningV1 is sent for PipelineRuns with "ConditionSucceeded" "Unknown"
// once the PipelineRun is validated and Pod created
TektonPipelineRunRunningV1 TektonEventType = "dev.tekton.event.pipelinerun.running.v1"
// TektonPipelineRunUnknownV1 is sent for PipelineRuns with "ConditionSucceeded" "Unknown"
// It can be used as a confirmation that the PipelineRun is still running.
TektonPipelineRunUnknownV1 TektonEventType = "dev.tekton.event.pipelinerun.unknown.v1"
// TektonPipelineRunSuccessfulV1 is sent for PipelineRuns with "ConditionSucceeded" "True"
TektonPipelineRunSuccessfulV1 TektonEventType = "dev.tekton.event.pipelinerun.successful.v1"
// TektonPipelineRunFailedV1 is sent for PipelineRuns with "ConditionSucceeded" "False"
TektonPipelineRunFailedV1 TektonEventType = "dev.tekton.event.pipelinerun.failed.v1"
)

func (t TektonEventType) String() string {
Expand All @@ -51,35 +72,47 @@ func (t TektonEventType) String() string {
type CEClient cloudevents.Client

// TektonCloudEventData type is used to marshal and unmarshal the payload of
// a Tekton cloud event. It only includes a TaskRun for now. Using a type opens
// the possibility for the future to add more data to the payload
// a Tekton cloud event. It can include a PipelineRun or a PipelineRun or both
type TektonCloudEventData struct {
TaskRun *v1beta1.TaskRun `json:"taskRun"`
TaskRun *v1beta1.TaskRun `json:"taskRun,omitempty"`
PipelineRun *v1beta1.PipelineRun `json:"taskRun,omitempty"`
}

// NewTektonCloudEventData returns a new instance of NewTektonCloudEventData
func NewTektonCloudEventData(taskRun *v1beta1.TaskRun) TektonCloudEventData {
return TektonCloudEventData{
TaskRun: taskRun,
func NewTektonCloudEventData(taskRun *v1beta1.TaskRun, pipelineRun *v1beta1.PipelineRun) TektonCloudEventData {
tektonCloudEventData := TektonCloudEventData{}
if taskRun != nil {
tektonCloudEventData.TaskRun = taskRun
}
if pipelineRun != nil {
tektonCloudEventData.PipelineRun = pipelineRun
}
return tektonCloudEventData
}

// EventForTaskRun will create a new event based on a TaskRun,
// or return an error if not possible.
func EventForTaskRun(taskRun *v1beta1.TaskRun) (*cloudevents.Event, error) {
func EventForTaskRun(taskRun *v1beta1.TaskRun, reason *string) (*cloudevents.Event, error) {
// Check if the TaskRun is defined
if taskRun == nil {
return nil, errors.New("Cannot send an event for an empty TaskRun")
}
event := cloudevents.NewEvent()
event.SetID(uuid.New().String())
event.SetSubject(taskRun.ObjectMeta.Name)
event.SetSource(taskRun.ObjectMeta.SelfLink) // TODO: SelfLink is deprecated
event.SetSource(taskRun.ObjectMeta.SelfLink) // TODO: SelfLink is deprecated https://github.com/tektoncd/pipeline/issues/2676

c := taskRun.Status.GetCondition(apis.ConditionSucceeded)
switch {
case c.IsUnknown():
event.SetType(TektonTaskRunUnknownV1.String())
switch reason {
case events.EventReasonStarted:
event.SetType(TektonTaskRunStartedV1.String())
case events.EventReasonRunning:
event.SetType(TektonTaskRunRunningV1.String())
default:
event.SetType(TektonTaskRunUnknownV1.String())
}
case c.IsFalse():
event.SetType(TektonTaskRunFailedV1.String())
case c.IsTrue():
Expand Down
2 changes: 1 addition & 1 deletion pkg/reconciler/events/cloudevent/cloudevent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func TestEventForTaskRun(t *testing.T) {
t.Run(c.desc, func(t *testing.T) {
names.TestingSeed()

got, err := EventForTaskRun(c.taskRun)
got, err := EventForTaskRun(c.taskRun, nil)
if err != nil {
t.Fatalf("I did not expect an error but I got %s", err)
} else {
Expand Down

0 comments on commit 17d8b41

Please sign in to comment.