diff --git a/backend/pipeline/adapter.go b/backend/pipeline/adapter.go index 024b36db69..60c1f91c99 100644 --- a/backend/pipeline/adapter.go +++ b/backend/pipeline/adapter.go @@ -2,6 +2,7 @@ package pipeline import ( "context" + "fmt" corev2 "github.com/sensu/sensu-go/api/core/v2" ) @@ -14,9 +15,28 @@ type Adapter interface { Run(context.Context, *corev2.ResourceReference, interface{}) error } +// ErrMisconfiguredPipeline interface implemented by errors that indicate +// a misconfigured pipeline that cannot be executed. +type ErrMisconfiguredPipeline interface { + MisconfiguredPipeline() +} + // ErrNoWorkflows is returned when a pipeline has no workflows type ErrNoWorkflows struct{} func (e *ErrNoWorkflows) Error() string { return "pipeline has no workflows" } + +func (e *ErrNoWorkflows) MisconfiguredPipeline() {} + +// ErrNoLegacyHandlers is returned when no legacy handlers exist +type errNoLegacyHandlers struct { + Msg string +} + +func (e *errNoLegacyHandlers) Error() string { + return fmt.Sprintf("legacy pipeline found no existing handlers: %s", e.Msg) +} + +func (e *errNoLegacyHandlers) MisconfiguredPipeline() {} diff --git a/backend/pipeline/adapterv1.go b/backend/pipeline/adapterv1.go index 195bfaf7d5..a35b5c58b0 100644 --- a/backend/pipeline/adapterv1.go +++ b/backend/pipeline/adapterv1.go @@ -285,6 +285,12 @@ func (a *AdapterV1) generateLegacyPipeline(ctx context.Context, event *corev2.Ev return nil, err } + if len(handlers) < 1 { + return nil, &errNoLegacyHandlers{ + Msg: fmt.Sprintf("none of %s exist", legacyHandlerNames), + } + } + pipeline := &corev2.Pipeline{ ObjectMeta: corev2.ObjectMeta{ Name: LegacyPipelineName, diff --git a/backend/pipeline/adapterv1_test.go b/backend/pipeline/adapterv1_test.go index d9b909f08c..4d46921312 100644 --- a/backend/pipeline/adapterv1_test.go +++ b/backend/pipeline/adapterv1_test.go @@ -535,17 +535,62 @@ func TestAdapterV1_resolvePipelineReference(t *testing.T) { }, event: func() *corev2.Event { event := corev2.FixtureEvent("entity1", "check1") + event.Check.Handlers = []string{"myhandler"} return event }(), }, + fields: fields{ + Store: func() store.Store { + handler := &corev2.Handler{ + ObjectMeta: corev2.NewObjectMeta("myhandler", "default"), + } + stor := &mockstore.MockStore{} + stor.On("GetHandlerByName", mock.Anything, handler.GetName()). + Return(handler, nil) + return stor + }(), + }, want: func() *corev2.Pipeline { pipeline := &corev2.Pipeline{ ObjectMeta: corev2.NewObjectMeta("legacy-pipeline", "default"), - Workflows: []*corev2.PipelineWorkflow{}, + Workflows: []*corev2.PipelineWorkflow{ + { + Name: "legacy-pipeline-workflow-myhandler", + Handler: &corev2.ResourceReference{ + Type: "Handler", + APIVersion: "core/v2", + Name: "myhandler", + }, + }, + }, } return pipeline }(), }, + { + name: "returns error when ref name is legacy-pipeline but no handlers exist", + args: args{ + ctx: context.WithValue(context.Background(), corev2.NamespaceKey, "default"), + ref: &corev2.ResourceReference{ + Name: "legacy-pipeline", + }, + event: func() *corev2.Event { + event := corev2.FixtureEvent("entity1", "check1") + event.Check.Handlers = []string{"myhandler"} + return event + }(), + }, + fields: fields{ + Store: func() store.Store { + var missingHandler *corev2.Handler + stor := &mockstore.MockStore{} + stor.On("GetHandlerByName", mock.Anything, mock.Anything). + Return(missingHandler, nil) + return stor + }(), + }, + wantErr: true, + }, { name: "returns a stored pipeline if the ref name is not legacy-pipeline", args: args{ diff --git a/backend/pipelined/pipelined.go b/backend/pipelined/pipelined.go index 2517d0dbd4..3f7fbf8427 100644 --- a/backend/pipelined/pipelined.go +++ b/backend/pipelined/pipelined.go @@ -248,11 +248,14 @@ func (p *Pipelined) handleMessage(ctx context.Context, msg interface{}) (hadPipe return true, err } skipPipelineErr := fmt.Errorf("%w, skipping execution of pipeline", err) - if _, ok := err.(*pipeline.ErrNoWorkflows); ok { - if fields["check_name"] != "keepalive" { - // only warn about empty pipelines if it's not a keepalive. - // this reduces log spam. - logger.WithFields(fields).Warn(skipPipelineErr) + if _, ok := err.(pipeline.ErrMisconfiguredPipeline); ok { + if fields["check_name"] == "keepalive" { + // supress logging for keepalive events to debug. + // default "keepalive" handler is added to keepalive events + // which frequently generates log noise. + logger.WithFields(fields).Debug(skipPipelineErr) + } else { + logger.WithFields(fields).Info(skipPipelineErr) } } else { logger.WithFields(fields).Error(skipPipelineErr)