github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/gadgets/interface.go (about)

     1  // Copyright 2022-2023 The Inspektor Gadget authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package gadgets
    16  
    17  import (
    18  	"github.com/inspektor-gadget/inspektor-gadget/pkg/params"
    19  	"github.com/inspektor-gadget/inspektor-gadget/pkg/parser"
    20  )
    21  
    22  // GadgetType defines how a gadget is actually run
    23  type GadgetType string
    24  
    25  const (
    26  	TypeUnknown        GadgetType = ""
    27  	TypeTrace          GadgetType = "trace"          // Normal trace gadgets
    28  	TypeTraceIntervals GadgetType = "traceIntervals" // top gadgets expecting arrays of events
    29  	TypeOneShot        GadgetType = "oneShot"        // Gadgets that only fetch results
    30  	TypeProfile        GadgetType = "profile"        // Gadgets that run until the user stops, or it times out and then shows results
    31  	TypeRun            GadgetType = "run"            // This is a special type only used by the run command
    32  	TypeOther          GadgetType = "other"
    33  )
    34  
    35  func (t GadgetType) CanSort() bool {
    36  	return t == TypeOneShot || t == TypeTraceIntervals
    37  }
    38  
    39  func (t GadgetType) IsPeriodic() bool {
    40  	return t == TypeTraceIntervals
    41  }
    42  
    43  // GadgetDesc is the main interface for handling gadgets
    44  type GadgetDesc interface {
    45  	// Name provides the name of the gadget. This is used for the calling the gadget, auto-creating the cobra commands,
    46  	// logging, etc.
    47  	Name() string
    48  
    49  	// Description provides a short description of the gadget. This is used for a quick help in cobra, help,
    50  	// web-interface etc.
    51  	Description() string
    52  
    53  	// Category is used for cobra sub-commands and categories on the web interface.
    54  	Category() string
    55  
    56  	// Type is used to differentiate between how gadgets are run. The type essentially controls the workflow of the
    57  	// gadget.
    58  	Type() GadgetType
    59  
    60  	// ParamDescs returns a map of configuration parameters. These hold also default values, descriptions, validators and
    61  	// so on. Used whenever a gadget is called somehow. Auto-creates parameters for cobra as well.
    62  	ParamDescs() params.ParamDescs
    63  
    64  	// Parser returns a parser.Parser instance that can handle events and do certain operations on them
    65  	// (sorting, filtering, etc.) without the caller needing to know about the underlying types.
    66  	Parser() parser.Parser
    67  
    68  	// EventPrototype returns a blank event. Useful for checking for interfaces on it (see operators).
    69  	EventPrototype() any
    70  }
    71  
    72  // Optional extensions to GadgetDesc
    73  
    74  // GadgetDescSkipParams / SkipParams() can define params that a gadget, runtime or operators never can use in
    75  // combination with this gadget. Currently, this is used to not allow to specify for example a container name
    76  // when the gadget is working inside the kubernetes environment and using the netns (as results could be ambiguous in
    77  // that case).
    78  type GadgetDescSkipParams interface {
    79  	SkipParams() []params.ValueHint
    80  }
    81  
    82  type OutputFormats map[string]OutputFormat
    83  
    84  // OutputFormat can hold alternative output formats for a gadget. Whenever
    85  // such a format is used, the result of the gadget will be passed to the Transform()
    86  // function and returned to the user.
    87  type OutputFormat struct {
    88  	Name                   string                    `json:"name"`
    89  	Description            string                    `json:"description"`
    90  	RequiresCombinedResult bool                      `json:"requiresCombinedResult"`
    91  	Transform              func(any) ([]byte, error) `json:"-"`
    92  }
    93  
    94  // Append appends the OutputFormats given in other to of
    95  func (of OutputFormats) Append(other OutputFormats) {
    96  	for k, v := range other {
    97  		of[k] = v
    98  	}
    99  }
   100  
   101  // GadgetOutputFormats can be implemented together with the gadget interface
   102  // to register alternative output formats that are used in combination with
   103  // the GadgetResult interface. The defaultFormatKey MUST match the key of
   104  // an entry in the supportedFormats map
   105  type GadgetOutputFormats interface {
   106  	OutputFormats() (supportedFormats OutputFormats, defaultFormatKey string)
   107  }
   108  
   109  type EventHandlerSetter interface {
   110  	SetEventHandler(handler any)
   111  }
   112  
   113  type EventHandlerArraySetter interface {
   114  	SetEventHandlerArray(handler any)
   115  }
   116  
   117  type EventEnricherSetter interface {
   118  	SetEventEnricher(func(ev any) error)
   119  }
   120  
   121  // RunGadget is an interface that will be implemented by gadgets that are run in
   122  // the background and emit events as soon as they occur.
   123  type RunGadget interface {
   124  	// Run is expected to run the gadget and emits the events using the
   125  	// EventHandler. This function is expected to be blocking and return only
   126  	// when the context is done, after which the gadget should clean up all
   127  	// resources. Notice that this function will be called after operators are
   128  	// installed.
   129  	Run(GadgetContext) error
   130  }
   131  
   132  // RunWithResultGadget is an alternative to RunGadget that returns the result
   133  // of the gadget only at the end of its execution.
   134  type RunWithResultGadget interface {
   135  	// RunWithResult follows the same rules as Run() but instead of using an
   136  	// EventHandler to emit the events, it returns the result of the gadget as a
   137  	// byte array after the context is done.
   138  	RunWithResult(GadgetContext) ([]byte, error)
   139  }
   140  
   141  // InitCloseGadget is an optional interface that can be implemented by gadgets
   142  // that needs to be initialized before the operators are installed. An example
   143  // of this is when the gadget needs to be kept up-to-date with the containers
   144  // that need to be traced, as the operators will start sending notifications of
   145  // this as soon as it is installed. So, the gadget needs to be initialized and
   146  // ready to receive those notifications before the operators are installed.
   147  type InitCloseGadget interface {
   148  	// Init is expected to initialize the gadget. It will be called right before
   149  	// the operators are installed, and also before Run() is called (which is
   150  	// done after the operators are installed, see the Gadget interface).
   151  	Init(GadgetContext) error
   152  
   153  	// Close is expected to clean up all the resources allocated by the gadget.
   154  	// It will be called after Run() returns and after the operators have been
   155  	// uninstalled.
   156  	// TODO: We should pass the gadget context to Close().
   157  	Close()
   158  }
   159  
   160  type Gadget any
   161  
   162  // GadgetInstantiate is the same interface as Gadget but adds one call to instantiate an actual
   163  // tracer
   164  type GadgetInstantiate interface {
   165  	GadgetDesc
   166  
   167  	// NewInstance creates a new gadget and returns it; the tracer should be allocated and configured but
   168  	// should not run any code that depends on cleanup
   169  	NewInstance() (Gadget, error)
   170  }
   171  
   172  // GadgetExperimental allows to mark a gadget as experimental.
   173  type GadgetExperimental interface {
   174  	Experimental() bool
   175  }