From 17d8b419a61f12e456f907dd48f0ac1a02f4ac6a Mon Sep 17 00:00:00 2001 From: Andrea Frittoli Date: Fri, 22 May 2020 18:00:35 +0100 Subject: [PATCH] WIP Add support for more cloud events 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. --- .../cloudevent/cloud_event_controller.go | 2 +- .../events/cloudevent/cloudevent.go | 57 +++++++++++++++---- .../events/cloudevent/cloudevent_test.go | 2 +- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/pkg/reconciler/events/cloudevent/cloud_event_controller.go b/pkg/reconciler/events/cloudevent/cloud_event_controller.go index 2bb69dd20fc..05ba2e1a0cb 100644 --- a/pkg/reconciler/events/cloudevent/cloud_event_controller.go +++ b/pkg/reconciler/events/cloudevent/cloud_event_controller.go @@ -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 diff --git a/pkg/reconciler/events/cloudevent/cloudevent.go b/pkg/reconciler/events/cloudevent/cloudevent.go index 25ed3aa734f..7dfaff032a4 100644 --- a/pkg/reconciler/events/cloudevent/cloudevent.go +++ b/pkg/reconciler/events/cloudevent/cloudevent.go @@ -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 { @@ -51,22 +72,27 @@ 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") @@ -74,12 +100,19 @@ func EventForTaskRun(taskRun *v1beta1.TaskRun) (*cloudevents.Event, error) { 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(): diff --git a/pkg/reconciler/events/cloudevent/cloudevent_test.go b/pkg/reconciler/events/cloudevent/cloudevent_test.go index aefaf847a78..3fc966dfc6f 100644 --- a/pkg/reconciler/events/cloudevent/cloudevent_test.go +++ b/pkg/reconciler/events/cloudevent/cloudevent_test.go @@ -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 {