github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/fanal/handler/handler.go (about)

     1  package handler
     2  
     3  import (
     4  	"context"
     5  	"sort"
     6  
     7  	"golang.org/x/exp/slices"
     8  	"golang.org/x/xerrors"
     9  
    10  	"github.com/devseccon/trivy/pkg/fanal/analyzer"
    11  	"github.com/devseccon/trivy/pkg/fanal/artifact"
    12  	"github.com/devseccon/trivy/pkg/fanal/types"
    13  )
    14  
    15  var (
    16  	postHandlerInits = make(map[types.HandlerType]postHandlerInit)
    17  )
    18  
    19  type postHandlerInit func(artifact.Option) (PostHandler, error)
    20  
    21  type PostHandler interface {
    22  	Type() types.HandlerType
    23  	Version() int
    24  	Handle(context.Context, *analyzer.AnalysisResult, *types.BlobInfo) error
    25  	Priority() int
    26  }
    27  
    28  // RegisterPostHandlerInit adds a constructor of post handler
    29  func RegisterPostHandlerInit(t types.HandlerType, init postHandlerInit) {
    30  	postHandlerInits[t] = init
    31  }
    32  
    33  func DeregisterPostHandler(t types.HandlerType) {
    34  	delete(postHandlerInits, t)
    35  }
    36  
    37  type Manager struct {
    38  	postHandlers []PostHandler
    39  }
    40  
    41  func NewManager(artifactOpt artifact.Option) (Manager, error) {
    42  	var m Manager
    43  	for t, handlerInit := range postHandlerInits {
    44  		// Skip the handler if it is disabled
    45  		if slices.Contains(artifactOpt.DisabledHandlers, t) {
    46  			continue
    47  		}
    48  		handler, err := handlerInit(artifactOpt)
    49  		if err != nil {
    50  			return Manager{}, xerrors.Errorf("post handler %s initialize error: %w", t, err)
    51  		}
    52  
    53  		m.postHandlers = append(m.postHandlers, handler)
    54  	}
    55  
    56  	// Sort post handlers by priority
    57  	sort.Slice(m.postHandlers, func(i, j int) bool {
    58  		return m.postHandlers[i].Priority() > m.postHandlers[j].Priority()
    59  	})
    60  
    61  	return m, nil
    62  }
    63  
    64  func (m Manager) Versions() map[string]int {
    65  	versions := make(map[string]int)
    66  	for _, h := range m.postHandlers {
    67  		versions[string(h.Type())] = h.Version()
    68  	}
    69  	return versions
    70  }
    71  
    72  func (m Manager) PostHandle(ctx context.Context, result *analyzer.AnalysisResult, blob *types.BlobInfo) error {
    73  	for _, h := range m.postHandlers {
    74  		if err := h.Handle(ctx, result, blob); err != nil {
    75  			return xerrors.Errorf("post handler error: %w", err)
    76  		}
    77  	}
    78  	return nil
    79  }