Skip to content

Commit

Permalink
chore(events): export parse functions as a go module
Browse files Browse the repository at this point in the history
  • Loading branch information
AlonZivony committed Jun 1, 2024
1 parent dab8d93 commit 794c93b
Show file tree
Hide file tree
Showing 11 changed files with 262 additions and 183 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,5 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
kernel.org/pub/linux/libs/security/libcap/psx v1.2.69 // indirect
)

replace github.com/aquasecurity/tracee/pkg/events/parsers => ./pkg/events/parsers
7 changes: 2 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1174,14 +1174,11 @@ golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
Expand Down Expand Up @@ -1430,8 +1427,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
25 changes: 23 additions & 2 deletions pkg/ebpf/events_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ import (
"bytes"
"context"
"encoding/binary"
"fmt"
"strconv"
"sync"
"unsafe"

bpf "github.com/aquasecurity/libbpfgo"

"github.com/aquasecurity/tracee/pkg/bufferdecoder"
"github.com/aquasecurity/tracee/pkg/errfmt"
"github.com/aquasecurity/tracee/pkg/events"
"github.com/aquasecurity/tracee/pkg/events/parsers"
"github.com/aquasecurity/tracee/pkg/logger"
"github.com/aquasecurity/tracee/pkg/policy"
"github.com/aquasecurity/tracee/pkg/utils"
Expand Down Expand Up @@ -724,13 +728,30 @@ func (t *Tracee) handleError(err error) {
// printers).
func (t *Tracee) parseArguments(e *trace.Event) error {
if t.config.Output.ParseArguments {
err := events.ParseArgs(e)
err := parsers.ParseArgs(e)
if err != nil {
return errfmt.WrapError(err)
}

if t.config.Output.ParseArgumentsFDs {
return events.ParseArgsFDs(e, uint64(t.getOrigEvtTimestamp(e)), t.FDArgPathMap)
return parseArgsFDs(e, uint64(t.getOrigEvtTimestamp(e)), t.FDArgPathMap)
}
}

return nil
}

func parseArgsFDs(event *trace.Event, origTimestamp uint64, fdArgPathMap *bpf.BPFMap) error {
if fdArg := parsers.GetArg(event, "fd"); fdArg != nil {
if fd, isInt32 := fdArg.Value.(int32); isInt32 {
ts := origTimestamp
bs, err := fdArgPathMap.GetValue(unsafe.Pointer(&ts))
if err != nil {
return errfmt.WrapError(err)
}

fpath := string(bytes.Trim(bs, "\x00"))
fdArg.Value = fmt.Sprintf("%d=%s", fd, fpath)
}
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/ebpf/net_capture.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/google/gopacket/layers"

"github.com/aquasecurity/tracee/pkg/events"
"github.com/aquasecurity/tracee/pkg/events/parsers"
"github.com/aquasecurity/tracee/pkg/logger"
"github.com/aquasecurity/tracee/types/trace"
)
Expand Down Expand Up @@ -103,7 +104,7 @@ func (t *Tracee) processNetCapEvent(event *trace.Event) {

// sanity checks

payloadArg := events.GetArg(event, "payload")
payloadArg := parsers.GetArg(event, "payload")
if payloadArg == nil {
logger.Debugw("Network capture: no payload packet")
return
Expand Down
13 changes: 7 additions & 6 deletions pkg/ebpf/processor_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/aquasecurity/tracee/pkg/errfmt"
"github.com/aquasecurity/tracee/pkg/events"
"github.com/aquasecurity/tracee/pkg/events/parse"
"github.com/aquasecurity/tracee/pkg/events/parsers"
"github.com/aquasecurity/tracee/pkg/filehash"
"github.com/aquasecurity/tracee/pkg/logger"
"github.com/aquasecurity/tracee/pkg/utils"
Expand Down Expand Up @@ -102,7 +103,7 @@ func (t *Tracee) processReadEvent(event *trace.Event) error {

// processKernelReadFile processes a security read event and changes the read type value.
func processKernelReadFile(event *trace.Event) error {
readTypeArg := events.GetArg(event, "type")
readTypeArg := parsers.GetArg(event, "type")
readTypeInt, ok := readTypeArg.Value.(int32)
if !ok {
return errfmt.Errorf("missing argument %s in event %s", "type", event.EventName)
Expand Down Expand Up @@ -287,7 +288,7 @@ func (t *Tracee) processHookedProcFops(event *trace.Event) error {
}
hookedFops = append(hookedFops, trace.HookedSymbolData{SymbolName: functionName, ModuleOwner: hookingFunction.Owner})
}
err = events.SetArgValue(event, hookedFopsPointersArgName, hookedFops)
err = parsers.SetArgValue(event, hookedFopsPointersArgName, hookedFops)
if err != nil {
return err
}
Expand Down Expand Up @@ -326,15 +327,15 @@ func (t *Tracee) processPrintMemDump(event *trace.Event) error {
return errfmt.WrapError(err)
}
arch = string(bytes.TrimRight(utsName.Machine[:], "\x00"))
err = events.SetArgValue(event, "arch", arch)
err = parsers.SetArgValue(event, "arch", arch)
if err != nil {
return err
}
err = events.SetArgValue(event, "symbol_name", symbol.Name)
err = parsers.SetArgValue(event, "symbol_name", symbol.Name)
if err != nil {
return err
}
err = events.SetArgValue(event, "symbol_owner", symbol.Owner)
err = parsers.SetArgValue(event, "symbol_owner", symbol.Owner)
if err != nil {
return err
}
Expand Down Expand Up @@ -394,7 +395,7 @@ func (t *Tracee) processSchedProcessFork(event *trace.Event) error {
// normalizeEventArgTime normalizes the event arg time to be relative to tracee start time or
// current time.
func (t *Tracee) normalizeEventArgTime(event *trace.Event, argName string) error {
arg := events.GetArg(event, argName)
arg := parsers.GetArg(event, argName)
if arg == nil {
return errfmt.Errorf("couldn't find argument %s of event %s", argName, event.EventName)
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/events/derive/net_packet_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/google/gopacket/layers"

"github.com/aquasecurity/tracee/pkg/dnscache"
"github.com/aquasecurity/tracee/pkg/events"
"github.com/aquasecurity/tracee/pkg/events/parsers"
"github.com/aquasecurity/tracee/pkg/logger"
"github.com/aquasecurity/tracee/types/trace"
)
Expand Down Expand Up @@ -82,7 +82,7 @@ func strToLower(given string) string {

// parsePayloadArg returns the packet payload from the event.
func parsePayloadArg(event *trace.Event) ([]byte, error) {
payloadArg := events.GetArg(event, "payload")
payloadArg := parsers.GetArg(event, "payload")
if payloadArg == nil {
return nil, noPayloadError()
}
Expand Down
89 changes: 63 additions & 26 deletions pkg/events/parsers/data_parsers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ import (
"strings"
"sync/atomic"

"github.com/moby/moby/pkg/parsers/kernel"
"golang.org/x/sys/unix"

"github.com/aquasecurity/tracee/pkg/utils/environment"
)

type SystemFunctionArgument interface {
Expand Down Expand Up @@ -264,7 +263,10 @@ func ParseOpenFlagArgument(rawValue uint64) (OpenFlagArgument, error) {
}

if len(f) == 0 {
return OpenFlagArgument{}, fmt.Errorf("no valid open flag values present in raw value: 0x%x", rawValue)
return OpenFlagArgument{}, fmt.Errorf(
"no valid open flag values present in raw value: 0x%x",
rawValue,
)
}

return OpenFlagArgument{rawValue: rawValue, stringValue: strings.Join(f, "|")}, nil
Expand Down Expand Up @@ -3262,7 +3264,7 @@ func ParseLegacyGUPFlags(rawValue uint64) LegacyGUPFlag {
var currentOSGUPFlagsParse uint32
var skipDetermineGUPFlagsFunc uint32

const gupFlagsChangeVersion = "6.3.0"
var gupFlagsChangeVersion, _ = kernel.ParseRelease("6.3.0")

// ParseGUPFlagsCurrentOS parse the GUP flags received according to current machine OS version.
// It uses optimizations to perform better than ParseGUPFlagsForOS
Expand All @@ -3272,21 +3274,14 @@ func ParseGUPFlagsCurrentOS(rawValue uint64) (SystemFunctionArgument, error) {
legacyParsing
)
if atomic.LoadUint32(&skipDetermineGUPFlagsFunc) == 0 {
osInfo, err := environment.GetOSInfo()
if err != nil {
return nil, fmt.Errorf("error getting current OS info - %s", err)
}
compare, err := osInfo.CompareOSBaseKernelRelease(gupFlagsChangeVersion)
currentVersion, err := kernel.GetKernelVersion()
if err != nil {
return nil, fmt.Errorf(
"error comparing OS versions to determine how to parse GUP flags - %s",
err,
)
return nil, fmt.Errorf("error getting current kernel version - %s", err)
}
if compare == environment.KernelVersionOlder {
atomic.StoreUint32(&currentOSGUPFlagsParse, legacyParsing)
} else {
if kernel.CompareKernelVersion(*currentVersion, *gupFlagsChangeVersion) >= 0 {
atomic.StoreUint32(&currentOSGUPFlagsParse, newVersionsParsing)
} else {
atomic.StoreUint32(&currentOSGUPFlagsParse, legacyParsing)
}
// Avoid doing this check in the future
atomic.StoreUint32(&skipDetermineGUPFlagsFunc, 1)
Expand All @@ -3305,19 +3300,17 @@ func ParseGUPFlagsCurrentOS(rawValue uint64) (SystemFunctionArgument, error) {
}

// ParseGUPFlagsForOS parse the GUP flags received according to given OS version.
func ParseGUPFlagsForOS(osInfo *environment.OSInfo, rawValue uint64) (SystemFunctionArgument, error) {
compare, err := osInfo.CompareOSBaseKernelRelease(gupFlagsChangeVersion)
func ParseGUPFlagsForOS(kernelVersion string, rawValue uint64) (
SystemFunctionArgument, error,
) {
parsedVersion, err := kernel.ParseRelease(kernelVersion)
if err != nil {
return nil, fmt.Errorf(
"error comparing OS versions to determine how to parse GUP flags - %s",
err,
)
return nil, fmt.Errorf("error parsing given kernel version - %s", err)
}

if compare == environment.KernelVersionOlder {
return ParseLegacyGUPFlags(rawValue), nil
if kernel.CompareKernelVersion(*parsedVersion, *gupFlagsChangeVersion) >= 0 {
return ParseGUPFlags(rawValue), nil
}
return ParseGUPFlags(rawValue), nil
return ParseLegacyGUPFlags(rawValue), nil
}

// =====================================================
Expand Down Expand Up @@ -3589,3 +3582,47 @@ func ParseFsNotifyObjType(rawValue uint64) (FsNotifyObjType, error) {
}
return v, nil
}

// =====================================================

// BpfAttachType is the type of probe the BPF program was attach to.
// This type is not of the kernel, but unique to Tracee. It must match the
// `bpf_attach_type_e` enum in the bpf code.
type BpfAttachType struct {
rawValue int32
stringValue string
}

var (
BPF_RAW_TRACEPOINT = BpfAttachType{rawValue: 0, stringValue: "raw_tracepoint"}
PERF_TRACEPOINT = BpfAttachType{rawValue: 1, stringValue: "tracepoint"}
PERF_KPROBE = BpfAttachType{rawValue: 2, stringValue: "kprobe"}
PERF_KRETPROBE = BpfAttachType{rawValue: 3, stringValue: "kretprobe"}
PERF_UPROBE = BpfAttachType{rawValue: 4, stringValue: "uprobe"}
PERF_URETPROBE = BpfAttachType{rawValue: 5, stringValue: "uretprobe"}
)

var attachTypeMap = map[int32]BpfAttachType{
int32(BPF_RAW_TRACEPOINT.Value()): BPF_RAW_TRACEPOINT,
int32(PERF_TRACEPOINT.Value()): PERF_TRACEPOINT,
int32(PERF_KPROBE.Value()): PERF_KPROBE,
int32(PERF_KRETPROBE.Value()): PERF_KRETPROBE,
int32(PERF_UPROBE.Value()): PERF_UPROBE,
int32(PERF_URETPROBE.Value()): PERF_URETPROBE,
}

func (attachType BpfAttachType) Value() uint64 {
return uint64(attachType.rawValue)
}

func (attachType BpfAttachType) String() string {
return attachType.stringValue
}

func ParseBpfAttachType(attachType int32) (BpfAttachType, error) {
v, ok := attachTypeMap[attachType]
if !ok {
return BpfAttachType{}, fmt.Errorf("not a valid argument: %d", attachType)
}
return v, nil
}
22 changes: 22 additions & 0 deletions pkg/events/parsers/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module tracee/pkg/events/parsers

go 1.21

require (
github.com/aquasecurity/tracee/types v0.0.0-20240531175500-73839cfd71e6
github.com/moby/moby v26.1.3+incompatible
github.com/stretchr/testify v1.9.0
golang.org/x/sys v0.20.0
)

require (
github.com/containerd/log v0.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.1 // indirect
)
42 changes: 42 additions & 0 deletions pkg/events/parsers/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
github.com/aquasecurity/tracee/types v0.0.0-20240531175500-73839cfd71e6 h1:2rCXNs7elaI1EWSyVNMsOmOMulnhcxSUQVY2ykgym+4=
github.com/aquasecurity/tracee/types v0.0.0-20240531175500-73839cfd71e6/go.mod h1:J0f9nzJWrFmFgMoK0s4Yirfh82vfKMatXytd1YdfU2I=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/moby/moby v26.1.3+incompatible h1:gIzra6kadTUzPUZWpyUfkaLKymz9I8gANMB1NKk2pF0=
github.com/moby/moby v26.1.3+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
Loading

0 comments on commit 794c93b

Please sign in to comment.