diff --git a/go.mod b/go.mod index fad34982..a8fe4fc0 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,9 @@ module github.com/kubescape/node-agent go 1.23.0 require ( + github.com/DmitriyVTitov/size v1.5.0 + github.com/anchore/syft v1.13.0 + github.com/aquilax/truncate v1.0.0 github.com/armosec/armoapi-go v0.0.470 github.com/armosec/utils-k8s-go v0.0.30 github.com/cenkalti/backoff/v4 v4.3.0 @@ -10,13 +13,16 @@ require ( github.com/crewjam/rfc5424 v0.1.0 github.com/cyphar/filepath-securejoin v0.3.3 github.com/deckarep/golang-set/v2 v2.6.0 + github.com/distribution/distribution v2.8.2+incompatible github.com/dustin/go-humanize v1.0.1 github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e github.com/evanphx/json-patch v5.9.0+incompatible github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb + github.com/gammazero/workerpool v1.1.3 github.com/go-openapi/strfmt v0.23.0 + github.com/google/go-containerregistry v0.20.2 github.com/google/uuid v1.6.0 - github.com/goradd/maps v0.1.5 + github.com/goradd/maps v1.0.0 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/inspektor-gadget/inspektor-gadget v0.33.0 github.com/kinbiko/jsonassert v1.1.1 @@ -24,6 +30,9 @@ require ( github.com/kubescape/go-logger v0.0.23 github.com/kubescape/k8s-interface v0.0.170 github.com/kubescape/storage v0.0.132 + github.com/moby/sys/mountinfo v0.7.2 + github.com/opencontainers/go-digest v1.0.0 + github.com/opencontainers/image-spec v1.1.0 github.com/panjf2000/ants/v2 v2.9.1 github.com/prometheus/alertmanager v0.27.0 github.com/prometheus/client_golang v1.20.4 @@ -38,11 +47,13 @@ require ( golang.org/x/net v0.29.0 golang.org/x/sys v0.25.0 gonum.org/v1/plot v0.14.0 + google.golang.org/grpc v1.67.1 gopkg.in/mcuadros/go-syslog.v2 v2.3.0 istio.io/pkg v0.0.0-20231221211216-7635388a563e k8s.io/api v0.31.1 k8s.io/apimachinery v0.31.1 k8s.io/client-go v0.31.1 + k8s.io/cri-api v0.31.1 k8s.io/kubectl v0.31.0 k8s.io/kubelet v0.31.1 k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 @@ -50,21 +61,40 @@ require ( ) require ( + dario.cat/mergo v1.0.1 // indirect git.sr.ht/~sbinet/gg v0.5.0 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20231105174938-2b5cbb29f3e2 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect + github.com/CycloneDX/cyclonedx-go v0.9.1 // indirect + github.com/DataDog/zstd v1.5.5 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver v1.5.0 // indirect + github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Microsoft/hcsshim v0.12.5 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect github.com/acobaugh/osrelease v0.1.0 // indirect + github.com/adrg/xdg v0.5.0 // indirect github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b // indirect + github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa // indirect + github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d // indirect + github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537 // indirect github.com/anchore/go-logger v0.0.0-20240217160628-ee28a485904f // indirect + github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb // indirect + github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect + github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4 // indirect github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f // indirect github.com/anchore/stereoscope v0.0.3 // indirect - github.com/anchore/syft v1.13.0 // indirect + github.com/andybalholm/brotli v1.1.0 // indirect + github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 // indirect + github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 // indirect github.com/armosec/gojay v1.2.17 // indirect github.com/armosec/utils-go v0.0.57 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/becheran/wildmatch-go v1.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect @@ -73,7 +103,10 @@ require ( github.com/campoy/embedmd v1.0.0 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/charmbracelet/lipgloss v0.13.0 // indirect + github.com/charmbracelet/x/ansi v0.2.3 // indirect github.com/cilium/cilium v1.16.4 // indirect + github.com/cloudflare/circl v1.3.8 // indirect github.com/containerd/cgroups/v3 v3.0.3 // indirect github.com/containerd/containerd v1.7.22 // indirect github.com/containerd/containerd/api v1.7.19 // indirect @@ -82,20 +115,27 @@ require ( github.com/containerd/fifo v1.1.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/platforms v0.2.1 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect github.com/containerd/ttrpc v1.2.5 // indirect github.com/containerd/typeurl/v2 v2.1.1 // indirect github.com/containers/common v0.60.4 // indirect github.com/coreos/go-oidc v2.2.1+incompatible // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/cli v27.3.1+incompatible // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker v27.3.1+incompatible // indirect github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/docker/go-units v0.5.0 // indirect + github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect + github.com/edsrzf/mmap-go v1.1.0 // indirect + github.com/elliotchance/phpserialize v1.4.0 // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/facebookincubator/nvdtools v0.1.5 // indirect github.com/fatih/color v1.17.0 // indirect github.com/felixge/fgprof v0.9.4 // indirect @@ -104,9 +144,13 @@ require ( github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.5 // indirect + github.com/gammazero/deque v0.2.0 // indirect github.com/github/go-spdx/v2 v2.3.2 // indirect github.com/go-errors/errors v1.5.1 // indirect github.com/go-fonts/liberation v0.3.2 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-git/go-git/v5 v5.12.0 // indirect github.com/go-latex/latex v0.0.0-20231108140139-5c1ce85aa4ea // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -120,17 +164,21 @@ require ( github.com/go-openapi/swag v0.23.0 // indirect github.com/go-openapi/validate v0.24.0 // indirect github.com/go-pdf/fpdf v0.9.0 // indirect + github.com/go-restruct/restruct v1.2.0-alpha // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/go-containerregistry v0.20.2 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/licensecheck v0.3.1 // indirect + github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/gookit/color v1.5.4 // indirect github.com/gopacket/gopacket v1.2.0 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect @@ -138,26 +186,39 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect + github.com/huandu/xstrings v1.5.0 // indirect + github.com/iancoleman/strcase v0.3.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jinzhu/copier v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/pgzip v1.2.6 // indirect + github.com/knqyf263/go-rpmdb v0.1.1 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mackerelio/go-osstat v0.2.5 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/mholt/archiver/v3 v3.5.1 // indirect + github.com/microsoft/go-rustaudit v0.0.0-20220730194248-4b17361d90a5 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/moby v27.3.1+incompatible // indirect github.com/moby/spdystream v0.4.0 // indirect - github.com/moby/sys/mountinfo v0.7.2 // indirect github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/sys/signal v0.7.0 // indirect github.com/moby/sys/user v0.3.0 // indirect @@ -166,36 +227,51 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect + github.com/muesli/termenv v0.15.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/nwaples/rardecode v1.1.0 // indirect github.com/oklog/ulid v1.3.1 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/olvrng/ujson v1.1.0 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opencontainers/selinux v1.11.0 // indirect github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect + github.com/pborman/indent v1.2.1 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pkg/profile v1.7.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pquerna/cachecontrol v0.2.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.59.1 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/s3rj1k/go-fanotify/fanotify v0.0.0-20240229202106-bca3154da60a // indirect + github.com/saferwall/pe v1.5.4 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/sassoftware/go-rpmutils v0.4.0 // indirect github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e // indirect + github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d // indirect github.com/seccomp/libseccomp-golang v0.10.0 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/shopspring/decimal v1.4.0 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spdx/tools-golang v0.5.5 // indirect github.com/spf13/cast v1.7.0 // indirect github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace // indirect github.com/stripe/stripe-go/v74 v74.30.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/sylabs/sif/v2 v2.18.0 // indirect github.com/sylabs/squashfs v1.0.0 // indirect github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect github.com/therootcompany/xz v1.0.1 // indirect @@ -203,12 +279,18 @@ require ( github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 // indirect github.com/uptrace/opentelemetry-go-extra/otelzap v0.3.2 // indirect github.com/uptrace/uptrace-go v1.30.1 // indirect + github.com/vbatts/go-mtree v0.5.4 // indirect + github.com/vbatts/tar-split v0.11.5 // indirect + github.com/vifraa/gopom v1.0.0 // indirect github.com/vishvananda/netlink v1.3.1-0.20241022031324-976bd8de7d81 // indirect github.com/vishvananda/netns v0.0.4 // indirect github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 // indirect github.com/wagoodman/go-progress v0.0.0-20230925121702-07e42b3cdba0 // indirect github.com/x448/float16 v0.8.4 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/xlab/treeprint v1.2.0 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect @@ -230,27 +312,28 @@ require ( golang.org/x/crypto v0.27.0 // indirect golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/image v0.18.0 // indirect + golang.org/x/mod v0.21.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/term v0.24.0 // indirect golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.6.0 // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/genproto v0.0.0-20240515191416-fc5f0ca64291 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/grpc v1.67.1 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.31.1 // indirect k8s.io/apiserver v0.31.1 // indirect k8s.io/cli-runtime v0.31.1 // indirect k8s.io/component-base v0.31.1 // indirect - k8s.io/cri-api v0.31.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240812233141-91dab695df6f // indirect oras.land/oras-go/v2 v2.4.0 // indirect @@ -263,4 +346,4 @@ require ( replace github.com/vishvananda/netns => github.com/inspektor-gadget/netns v0.0.5-0.20230524185006-155d84c555d6 -replace github.com/goradd/maps => github.com/matthyx/maps v0.0.0-20241029072232-2f5d83d608a7 +replace github.com/inspektor-gadget/inspektor-gadget => github.com/matthyx/inspektor-gadget v0.0.0-20241129070941-011b03588cbe diff --git a/go.sum b/go.sum index 228d476f..d6f516b9 100644 --- a/go.sum +++ b/go.sum @@ -47,6 +47,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= @@ -65,13 +67,34 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25 github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CycloneDX/cyclonedx-go v0.9.1 h1:yffaWOZsv77oTJa/SdVZYdgAgFioCeycBUKkqS2qzQM= +github.com/CycloneDX/cyclonedx-go v0.9.1/go.mod h1:NE/EWvzELOFlG6+ljX/QeMlVt9VKcTwu8u0ccsACEsw= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= +github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DmitriyVTitov/size v1.5.0 h1:/PzqxYrOyOUX1BXj6J9OuVRVGe+66VL4D9FlUaW515g= +github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= +github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Microsoft/hcsshim v0.12.5 h1:bpTInLlDy/nDRWFVcefDZZ1+U8tS+rz3MxjKgu9boo0= github.com/Microsoft/hcsshim v0.12.5/go.mod h1:tIUGego4G1EN5Hb6KC90aDYiUI2dqLSTTOCjVNpOgZ8= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= +github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/acobaugh/osrelease v0.1.0 h1:Yb59HQDGGNhCj4suHaFQQfBps5wyoKLSSX/J/+UifRE= github.com/acobaugh/osrelease v0.1.0/go.mod h1:4bFEs0MtgHNHBrmHCt67gNisnabCRAlzdVasCEGHTWY= github.com/adrg/xdg v0.5.0 h1:dDaZvhMXatArP1NPHhnfaQUqWBLBsmx1h1HXQdMoFCY= @@ -88,8 +111,18 @@ github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa h1:pwlAn4O9SBUnlgfa69 github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa/go.mod h1:nD3H5uIvjxlfmakOBgtyFQbk5Zjp3l538kxfpHPslzI= github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d h1:ZD4wdCBgJJzJybjTUIEiiupLF7B9H3WLuBTjspBO2Mc= github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d/go.mod h1:Xh4ObY3fmoMzOEVXwDtS1uK44JC7+nRD0n29/1KYFYg= +github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537 h1:GjNGuwK5jWjJMyVppBjYS54eOiiSNv4Ba869k4wh72Q= +github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537/go.mod h1:1aiktV46ATCkuVg0O573ZrH56BUawTECPETbZyBcqT8= github.com/anchore/go-logger v0.0.0-20240217160628-ee28a485904f h1:qRQCz19ioRN2FtAct4j6Lb3Nl0VolFiuHtYMezGYBn0= github.com/anchore/go-logger v0.0.0-20240217160628-ee28a485904f/go.mod h1:ErB21zunlmQOE/aFPkt4Tv2Q00ttFxPZ2l87gSXxSec= +github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb h1:iDMnx6LIjtjZ46C0akqveX83WFzhpTD3eqOthawb5vU= +github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb/go.mod h1:DmTY2Mfcv38hsHbG78xMiTDdxFtkHpgYNVDPsF2TgHk= +github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc= +github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA= +github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 h1:VzprUTpc0vW0nnNKJfJieyH/TZ9UYAnTZs5/gHTdAe8= +github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04/go.mod h1:6dK64g27Qi1qGQZ67gFmBFvEHScy0/C8qhQhNe5B5pQ= +github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4 h1:rmZG77uXgE+o2gozGEBoUMpX27lsku+xrMwlmBZJtbg= +github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E= github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f h1:B/E9ixKNCasntpoch61NDaQyGPDXLEJlL+B9B/PbdbA= github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4= github.com/anchore/stereoscope v0.0.3 h1:JRPHySy8S6P+Ff3IDiQ29ap1i8/laUQxDk9K1eFh/2U= @@ -97,8 +130,19 @@ github.com/anchore/stereoscope v0.0.3/go.mod h1:5DJheGPjVRsSqegTB24Zi6SCHnYQnA51 github.com/anchore/syft v1.13.0 h1:cS7LBjalHPO5enCEtsyJrCSMAxTEE5BIB2nSmnS9uRQ= github.com/anchore/syft v1.13.0/go.mod h1:zL9Z5vtq8O+h6RRYo0lyb61NLx00OqcvoVNgk8qoMXA= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= +github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 h1:vmXNl+HDfqqXgr0uY1UgK1GAhps8nbAAtqHNBcgyf+4= +github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46/go.mod h1:olhPNdiiAAMiSujemd1O/sc6GcyePr23f/6uGKtthNg= +github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 h1:rcEG5HI490FF0a7zuvxOxen52ddygCfNVjP0XOCMl+M= +github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492/go.mod h1:9Beu8XsUNNfzml7WBf3QmyPToP1wm1Gj/Vc5UJKqTzU= +github.com/aquilax/truncate v1.0.0 h1:UgIGS8U/aZ4JyOJ2h3xcF5cSQ06+gGBnjxH2RUHJe0U= +github.com/aquilax/truncate v1.0.0/go.mod h1:BeMESIDMlvlS3bmg4BVvBbbZUNwWtS8uzYPAKXwwhLw= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= @@ -116,6 +160,10 @@ github.com/armosec/utils-k8s-go v0.0.30 h1:Gj8MJck0jZPSLSq8ZMiRPT3F/laOYQdaLxXKK github.com/armosec/utils-k8s-go v0.0.30/go.mod h1:t0vvPJhYE+X+bOsaMsD2SzWU7WkJmV2Ltn9hg66AIe8= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= +github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/becheran/wildmatch-go v1.0.0 h1:mE3dGGkTmpKtT4Z+88t8RStG40yN9T+kFEGj2PZFSzA= github.com/becheran/wildmatch-go v1.0.0/go.mod h1:gbMvj0NtVdJ15Mg/mH9uxk2R1QCistMyU7d9KFzroX4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -128,9 +176,12 @@ github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2y github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/briandowns/spinner v1.23.1 h1:t5fDPmScwUjozhDj4FA46p5acZWIPXYE30qW2Ptu650= github.com/briandowns/spinner v1.23.1/go.mod h1:LaZeM4wm2Ywy6vO571mvhQNRcWfRUnXOs0RcKV0wYKM= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY= github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= @@ -144,6 +195,16 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE= +github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU= +github.com/charmbracelet/bubbletea v1.1.1 h1:KJ2/DnmpfqFtDNVTvYZ6zpPFL9iRCRr0qqKOCvppbPY= +github.com/charmbracelet/bubbletea v1.1.1/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4= +github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw= +github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY= +github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqosGDEY= +github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= +github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0= +github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0= github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs= github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= @@ -160,6 +221,9 @@ github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEn github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.8 h1:j+V8jJt09PoeMFIu2uh5JUyEaIHTXVOHslFoLNAKqwI= +github.com/cloudflare/circl v1.3.8/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -186,6 +250,8 @@ github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= +github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= +github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= github.com/containerd/ttrpc v1.2.5 h1:IFckT1EFQoFBMG4c3sMdT8EP3/aKfumK1msY+Ze4oLU= github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4= @@ -199,6 +265,7 @@ github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7 github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.20 h1:VIPb/a2s17qNeQgDnkfZC35RScx+blkKF8GV68n80J4= @@ -213,11 +280,17 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da h1:ZOjWpVsFZ06eIhnh4mkaceTiVoktdU67+M7KDHJ268M= +github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da/go.mod h1:B3tI9iGHi4imdLi4Asdha1Sc6feLMTfPLXh9IUYmysk= github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4= +github.com/distribution/distribution v2.8.2+incompatible h1:k9+4DKdOG+quPFZXT/mUsiQrGu9vYCp+dXpuPkuqhk8= +github.com/distribution/distribution v2.8.2+incompatible/go.mod h1:EgLm2NgWtdKgzF9NpMzUKgzmR7AMmb0VQi2B+ZzDRjc= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ= github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= +github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= @@ -228,13 +301,24 @@ github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY= +github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= +github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e h1:rcHHSQqzCgvlwP0I/fQ8rQMn/MpHE5gWSLdtpxtP6KQ= github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e/go.mod h1:Byz7q8MSzSPkouskHJhX0er2mZY/m0Vj5bMeMCkkyY4= +github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= +github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elliotchance/phpserialize v1.4.0 h1:cAp/9+KSnEbUC8oYCE32n2n84BeW8HOY3HMDI8hG2OY= +github.com/elliotchance/phpserialize v1.4.0/go.mod h1:gt7XX9+ETUcLXbtTKEuyrqW3lcLUAeS/AnGZ2e49TZs= github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -246,6 +330,8 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/facebookincubator/flog v0.0.0-20190930132826-d2511d0ce33c/go.mod h1:QGzNH9ujQ2ZUr/CjDGZGWeDAVStrWNjHeEcjJL96Nuk= @@ -260,6 +346,7 @@ github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA= github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI= +github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= github.com/felixge/fgprof v0.9.4 h1:ocDNwMFlnA0NU0zSB3I52xkO4sFXk80VK9lXjLClu88= github.com/felixge/fgprof v0.9.4/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -277,10 +364,18 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= +github.com/gammazero/deque v0.2.0 h1:SkieyNB4bg2/uZZLxvya0Pq6diUlwx7m2TeT7GAIWaA= +github.com/gammazero/deque v0.2.0/go.mod h1:LFroj8x4cMYCukHJDbxFCkT+r9AndaJnFMuZDV34tuU= +github.com/gammazero/workerpool v1.1.3 h1:WixN4xzukFoN0XSeXF6puqEqFTl2mECI9S6W44HWy9Q= +github.com/gammazero/workerpool v1.1.3/go.mod h1:wPjyBLDbyKnUn2XwwyD3EEwo9dHutia9/fwNmSHWACc= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/github/go-spdx/v2 v2.3.2 h1:IfdyNHTqzs4zAJjXdVQfRnxt1XMfycXoHBE2Vsm1bjs= github.com/github/go-spdx/v2 v2.3.2/go.mod h1:2ZxKsOhvBp+OYBDlsGnUMcchLeo2mrpEBn2L1C+U3IQ= +github.com/glebarez/go-sqlite v1.20.3 h1:89BkqGOXR9oRmG58ZrzgoY/Fhy5x0M+/WV48U5zVrZ4= +github.com/glebarez/go-sqlite v1.20.3/go.mod h1:u3N6D/wftiAzIOJtZl6BmedqxmmkDfH3q+ihjqxC9u0= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= +github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= @@ -290,6 +385,14 @@ github.com/go-fonts/latin-modern v0.3.2 h1:M+Sq24Dp0ZRPf3TctPnG1MZxRblqyWC/cRUL9 github.com/go-fonts/latin-modern v0.3.2/go.mod h1:9odJt4NbRrbdj4UAMuLVd4zEukf6aAEKnDaQga0whqQ= github.com/go-fonts/liberation v0.3.2 h1:XuwG0vGHFBPRRI8Qwbi5tIvR3cku9LUfZGq/Ar16wlQ= github.com/go-fonts/liberation v0.3.2/go.mod h1:N0QsDLVUQPy3UYg9XAc3Uh3UDMp2Z7M1o4+X98dXkmI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -330,6 +433,8 @@ github.com/go-pdf/fpdf v0.9.0 h1:PPvSaUuo1iMi9KkaAn90NuKi+P4gwMedWPHhj8YlJQw= github.com/go-pdf/fpdf v0.9.0/go.mod h1:oO8N111TkmKb9D7VvWGLvLJlaZUQVPM+6V42pp3iV4Y= github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= +github.com/go-restruct/restruct v1.2.0-alpha h1:2Lp474S/9660+SJjpVxoKuWX09JsXHSrdV7Nv3/gkvc= +github.com/go-restruct/restruct v1.2.0-alpha/go.mod h1:KqrpKpn4M8OLznErihXTGLlsXFGeLxHUrLRRI/1YjGk= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= @@ -382,7 +487,10 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -411,6 +519,8 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/licensecheck v0.3.1 h1:QoxgoDkaeC4nFrtGN1jV7IPmDCHFNIVh54e5hSt6sPs= +github.com/google/licensecheck v0.3.1/go.mod h1:ORkR35t/JjW+emNKtfJDII0zlciG9JgbT7SmsohlHmY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -429,6 +539,7 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= @@ -450,6 +561,8 @@ github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/Q github.com/gopacket/gopacket v1.2.0 h1:eXbzFad7f73P1n2EJHQlsKuvIMJjVXK5tXoSca78I3A= github.com/gopacket/gopacket v1.2.0/go.mod h1:BrAKEy5EOGQ76LSqh7DMAr7z0NNPdczWm2GxCG7+I8M= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/goradd/maps v1.0.0 h1:21HC3xxKFk3p6BdQsELZXg/ByANMVYhCl0Mylzt0R38= +github.com/goradd/maps v1.0.0/go.mod h1:O3i5k17BAjHa9h5dzGWWfRJizF03umiBDZsNSqFdbVA= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -497,21 +610,24 @@ github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= +github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/inspektor-gadget/inspektor-gadget v0.33.0 h1:cUCVuGMY8m/SMNBfYvKLgW5n3cPBonUt9QGE6HVfXDo= -github.com/inspektor-gadget/inspektor-gadget v0.33.0/go.mod h1:Axsy1a2c1AaZCw+WJqX21Ibo9uTfxvY/PNCW5/ZwiO4= github.com/inspektor-gadget/netns v0.0.5-0.20230524185006-155d84c555d6 h1:fQqkJ+WkYfzy6BoUh32fr9uYrXfOGtsfw0skMQkfOic= github.com/inspektor-gadget/netns v0.0.5-0.20230524185006-155d84c555d6/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= @@ -529,12 +645,24 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953 h1:WdAeg/imY2JFPc/9CST4bZ80nNJbiBFCAdSZCSgrS5Y= +github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953/go.mod h1:6o+UrvuZWc4UTyBhQf0LGjW9Ld7qJxLz/OqvSOWWlEc= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kinbiko/jsonassert v1.1.1 h1:DB12divY+YB+cVpHULLuKePSi6+ui4M/shHSzJISkSE= github.com/kinbiko/jsonassert v1.1.1/go.mod h1:NO4lzrogohtIdNUNzx8sdzB55M4R4Q1bsrWVdqQ7C+A= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= +github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/knqyf263/go-rpmdb v0.1.1 h1:oh68mTCvp1XzxdU7EfafcWzzfstUZAEa3MW0IJye584= +github.com/knqyf263/go-rpmdb v0.1.1/go.mod h1:9LQcoMCMQ9vrF7HcDtXfvqGO4+ddxFQ8+YF/0CVGDww= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -560,6 +688,10 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= github.com/mackerelio/go-osstat v0.2.5 h1:+MqTbZUhoIt4m8qzkVoXUJg1EuifwlAJSk4Yl2GXh+o= @@ -570,8 +702,8 @@ github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3v github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matthyx/maps v0.0.0-20241029072232-2f5d83d608a7 h1:LAAFb3ra/vxiZcDY1zrbS29oqnB+N9MknuQZC1ju2+A= -github.com/matthyx/maps v0.0.0-20241029072232-2f5d83d608a7/go.mod h1:E5X1CHMgfVm1qFTHgXpgVLVylO5wtlhZdB93dRGjnc0= +github.com/matthyx/inspektor-gadget v0.0.0-20241129070941-011b03588cbe h1:/RdDR9sLzadGJN2rhFBIh1/gai0orgNwHtVTlLY6kdw= +github.com/matthyx/inspektor-gadget v0.0.0-20241129070941-011b03588cbe/go.mod h1:Axsy1a2c1AaZCw+WJqX21Ibo9uTfxvY/PNCW5/ZwiO4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -588,6 +720,11 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75 h1:P8UmIzZMYDR+NGImiFvErt6VWfIRPuGM+vyjiEdkmIw= +github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g= github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw= @@ -595,11 +732,17 @@ github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= +github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/microsoft/go-rustaudit v0.0.0-20220730194248-4b17361d90a5 h1:tQRHcLQwnwrPq2j2Qra/NnyjyESBGwdeBeVdAE9kXYg= +github.com/microsoft/go-rustaudit v0.0.0-20220730194248-4b17361d90a5/go.mod h1:vYT9HE7WCvL64iVeZylKmCsWKfE+JZ8105iuh2Trk8g= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= @@ -610,6 +753,8 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= @@ -641,16 +786,28 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= +github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ= +github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olvrng/ujson v1.1.0 h1:8xVUzVlqwdMVWh5d1UHBtLQ1D50nxoPuPEq9Wozs8oA= github.com/olvrng/ujson v1.1.0/go.mod h1:Mz4G3RODTUfbkKyvi0lgmPx/7vd3Saksk+1jgk8s9xo= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -679,14 +836,19 @@ github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144T github.com/pborman/indent v1.2.1 h1:lFiviAbISHv3Rf0jcuh489bi06hj98JsVMtIDZQb9yM= github.com/pborman/indent v1.2.1/go.mod h1:FitS+t35kIYtB5xWTZAPhnmrxcciEEOdbyrrpz5K6Vw= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -726,25 +888,45 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/s3rj1k/go-fanotify/fanotify v0.0.0-20240229202106-bca3154da60a h1:4VFls9SuqkqeioVevnaeTXrYKQ7JiEsxqKHfxp+/ovA= github.com/s3rj1k/go-fanotify/fanotify v0.0.0-20240229202106-bca3154da60a/go.mod h1:2zG1g57bc+D6FpNc68gsRXJgkidteqTMhWiiUP3m8UE= +github.com/saferwall/pe v1.5.4 h1:tLmMggEMUfeqrpJ25zS/okUQmyFdD5xWKL2+z9njCqg= +github.com/saferwall/pe v1.5.4/go.mod h1:mJx+PuptmNpoPFBNhWs/uDMFL/kTHVZIkg0d4OUJFbQ= github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= +github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= +github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA= +github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU= +github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= +github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg= +github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI= github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e h1:7q6NSFZDeGfvvtIRwBrU/aegEYJYmvev0cHAwo17zZQ= github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e/go.mod h1:DkpGd78rljTxKAnTDPFqXSGxvETQnJyuSOQwsHycqfs= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y= +github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= +github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d h1:RQqyEogx5J6wPdoxqL132b100j8KjcVHO1c0KLRoIhc= +github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d/go.mod h1:PegD7EVqlN88z7TpCqH92hHP+GBpfomGCCnw1PFtNOA= github.com/seccomp/libseccomp-golang v0.10.0 h1:aA4bp+/Zzi0BnWZ2F1wgNBs5gTpm+na2rWM6M9YjLpY= github.com/seccomp/libseccomp-golang v0.10.0/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -752,6 +934,8 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= @@ -772,17 +956,24 @@ github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spdx/gordf v0.0.0-20201111095634-7098f93598fb/go.mod h1:uKWaldnbMnjsSAXRurWqqrdyZen1R7kxl8TkmWk2OyM= +github.com/spdx/tools-golang v0.5.5 h1:61c0KLfAcNqAjlg6UNMdkwpMernhw3zVRwDZ2x9XOmk= +github.com/spdx/tools-golang v0.5.5/go.mod h1:MVIsXx8ZZzaRWNQpUDhC4Dud34edUYJYecciXgrw5vE= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= @@ -824,14 +1015,20 @@ github.com/stripe/stripe-go/v74 v74.30.0/go.mod h1:f9L6LvaXa35ja7eyvP6GQswoaIPaB github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/sylabs/sif/v2 v2.18.0 h1:eXugsS1qx7St2Wu/AJ21KnsQiVCpouPlTigABh+6KYI= +github.com/sylabs/sif/v2 v2.18.0/go.mod h1:GOQj7LIBqp15fjqH5i8ZEbLp8SXJi9S+xbRO+QQAdRo= github.com/sylabs/squashfs v1.0.0 h1:xAyMS21ogglkuR5HaY55PCfqY3H32ma9GkasTYo28Zg= github.com/sylabs/squashfs v1.0.0/go.mod h1:rhWzvgefq1X+R+LZdts10hfMsTg3g74OfGunW8tvg/4= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/terminalstatic/go-xsd-validate v0.1.5 h1:RqpJnf6HGE2CB/lZB1A8BYguk8uRtcvYAPLCF15qguo= +github.com/terminalstatic/go-xsd-validate v0.1.5/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw= github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw= github.com/therootcompany/xz v1.0.1/go.mod h1:3K3UH1yCKgBneZYhuQUvJ9HPD19UEXEI0BWbMn8qNMY= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 h1:3/aHKUq7qaFMWxyQV0W2ryNgg8x8rVeKVA20KJUkfS0= @@ -840,8 +1037,15 @@ github.com/uptrace/opentelemetry-go-extra/otelzap v0.3.2 h1:cj/Z6FKTTYBnstI0Lni9 github.com/uptrace/opentelemetry-go-extra/otelzap v0.3.2/go.mod h1:LDaXk90gKEC2nC7JH3Lpnhfu+2V7o/TsqomJJmqA39o= github.com/uptrace/uptrace-go v1.30.1 h1:9Bb3bIfPZ9LmtwAbKpN7+nX8iVwx+LmVe/CuiljFqxc= github.com/uptrace/uptrace-go v1.30.1/go.mod h1:Sy6C30poEuG7ecG4Rcy4cBrC/jw8qJGHonXO3bXS5aQ= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/vbatts/go-mtree v0.5.4 h1:OMAb8jaCyiFA7zXj0Zc/oARcxBDBoeu2LizjB8BVJl0= +github.com/vbatts/go-mtree v0.5.4/go.mod h1:5GqJbVhm9BBiCc4K5uc/c42FPgXulHaQs4sFUEfIWMo= +github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts= +github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= +github.com/vifraa/gopom v1.0.0 h1:L9XlKbyvid8PAIK8nr0lihMApJQg/12OBvMA28BcWh0= +github.com/vifraa/gopom v1.0.0/go.mod h1:oPa1dcrGrtlO37WPDBm5SqHAT+wTgF8An1Q71Z6Vv4o= github.com/vishvananda/netlink v1.3.1-0.20241022031324-976bd8de7d81 h1:9fkQcQYvtTr9ayFXuMfDMVuDt4+BYG9FwsGLnrBde0M= github.com/vishvananda/netlink v1.3.1-0.20241022031324-976bd8de7d81/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs= github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 h1:jIVmlAFIqV3d+DOxazTR9v+zgj8+VYuQBzPgBZvWBHA= @@ -850,6 +1054,16 @@ github.com/wagoodman/go-progress v0.0.0-20230925121702-07e42b3cdba0 h1:0KGbf+0SM github.com/wagoodman/go-progress v0.0.0-20230925121702-07e42b3cdba0/go.mod h1:jLXFoL31zFaHKAAyZUh+sxiTDFe1L1ZHrcK2T1itVKA= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= @@ -859,6 +1073,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= @@ -932,6 +1147,10 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -975,6 +1194,10 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1021,6 +1244,11 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1056,6 +1284,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -1105,6 +1335,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1128,15 +1359,24 @@ golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1148,6 +1388,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1212,12 +1455,16 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= gonum.org/v1/plot v0.14.0 h1:+LBDVFYwFe4LHhdP8coW6296MBEY4nQ+Y4vuUpJopcE= @@ -1406,6 +1653,8 @@ gopkg.in/mcuadros/go-syslog.v2 v2.3.0 h1:kcsiS+WsTKyIEPABJBJtoG0KkOS6yzvJ+/eZlhD gopkg.in/mcuadros/go-syslog.v2 v2.3.0/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1458,6 +1707,20 @@ k8s.io/kubelet v0.31.1 h1:aAxwVxGzbbMKKk/FnSjvkN52K3LdHhjhzmYcyGBuE0c= k8s.io/kubelet v0.31.1/go.mod h1:8ZbexYHqUO946gXEfFmnMZiK2UKRGhk7LlGvJ71p2Ig= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= +modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= +modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM= +modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= oras.land/oras-go/v2 v2.4.0 h1:i+Wt5oCaMHu99guBD0yuBjdLvX7Lz8ukPbwXdR7uBMs= oras.land/oras-go/v2 v2.4.0/go.mod h1:osvtg0/ClRq1KkydMAEu/IxFieyjItcsQ4ut4PPF+f8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/main.go b/main.go index 3e667efa..2f11f327 100644 --- a/main.go +++ b/main.go @@ -11,9 +11,16 @@ import ( "syscall" apitypes "github.com/armosec/armoapi-go/armotypes" + utilsmetadata "github.com/armosec/utils-k8s-go/armometadata" + mapset "github.com/deckarep/golang-set/v2" + containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" + beUtils "github.com/kubescape/backend/pkg/utils" + "github.com/kubescape/go-logger" + "github.com/kubescape/go-logger/helpers" + "github.com/kubescape/k8s-interface/k8sinterface" "github.com/kubescape/node-agent/pkg/applicationprofilemanager" applicationprofilemanagerv1 "github.com/kubescape/node-agent/pkg/applicationprofilemanager/v1" - cloudmetadata "github.com/kubescape/node-agent/pkg/cloudmetadata" + "github.com/kubescape/node-agent/pkg/cloudmetadata" "github.com/kubescape/node-agent/pkg/config" "github.com/kubescape/node-agent/pkg/containerwatcher/v1" "github.com/kubescape/node-agent/pkg/eventreporters/dnsmanager" @@ -43,6 +50,8 @@ import ( "github.com/kubescape/node-agent/pkg/rulemanager" rulemanagerv1 "github.com/kubescape/node-agent/pkg/rulemanager/v1" "github.com/kubescape/node-agent/pkg/sbomhandler/syfthandler" + "github.com/kubescape/node-agent/pkg/sbommanager" + sbommanagerv1 "github.com/kubescape/node-agent/pkg/sbommanager/v1" "github.com/kubescape/node-agent/pkg/seccompmanager" seccompmanagerv1 "github.com/kubescape/node-agent/pkg/seccompmanager/v1" "github.com/kubescape/node-agent/pkg/storage/v1" @@ -50,14 +59,6 @@ import ( "github.com/kubescape/node-agent/pkg/validator" "github.com/kubescape/node-agent/pkg/watcher/dynamicwatcher" "github.com/kubescape/node-agent/pkg/watcher/seccompprofilewatcher" - - utilsmetadata "github.com/armosec/utils-k8s-go/armometadata" - mapset "github.com/deckarep/golang-set/v2" - - beUtils "github.com/kubescape/backend/pkg/utils" - "github.com/kubescape/go-logger" - "github.com/kubescape/go-logger/helpers" - "github.com/kubescape/k8s-interface/k8sinterface" ) func main() { @@ -130,10 +131,8 @@ func main() { prometheusExporter = metricsmanager.NewMetricsMock() } - nodeName := os.Getenv(config.NodeNameEnvVar) - // Detect the container containerRuntime of the node - containerRuntime, err := utils.DetectContainerRuntimeViaK8sAPI(ctx, k8sClient, nodeName) + containerRuntime, err := utils.DetectContainerRuntimeViaK8sAPI(ctx, k8sClient, cfg.NodeName) if err != nil { logger.L().Ctx(ctx).Fatal("error detecting the container runtime", helpers.Error(err)) } @@ -143,7 +142,7 @@ func main() { // Create watchers dWatcher := dynamicwatcher.NewWatchHandler(k8sClient, storageClient.StorageClient, cfg.SkipNamespace) // create k8sObject cache - k8sObjectCache, err := k8scache.NewK8sObjectCache(nodeName, k8sClient) + k8sObjectCache, err := k8scache.NewK8sObjectCache(cfg.NodeName, k8sClient) if err != nil { logger.L().Ctx(ctx).Fatal("error creating K8sObjectCache", helpers.Error(err)) } @@ -216,7 +215,7 @@ func main() { var cloudMetadata *apitypes.CloudMetadata if cfg.EnableRuntimeDetection || cfg.EnableMalwareDetection { - cloudMetadata, err = cloudmetadata.GetCloudMetadata(ctx, k8sClient, nodeName) + cloudMetadata, err = cloudmetadata.GetCloudMetadata(ctx, k8sClient, cfg.NodeName) if err != nil { logger.L().Ctx(ctx).Error("error getting cloud metadata", helpers.Error(err)) } @@ -227,16 +226,16 @@ func main() { processManager = processmanagerv1.CreateProcessManager(ctx) // create ruleBinding cache - ruleBindingCache := rulebindingcachev1.NewCache(nodeName, k8sClient) + ruleBindingCache := rulebindingcachev1.NewCache(cfg.NodeName, k8sClient) dWatcher.AddAdaptor(ruleBindingCache) ruleBindingNotify = make(chan rulebinding.RuleBindingNotify, 100) ruleBindingCache.AddNotifier(&ruleBindingNotify) - apc := applicationprofilecache.NewApplicationProfileCache(nodeName, storageClient.StorageClient, cfg.MaxDelaySeconds) + apc := applicationprofilecache.NewApplicationProfileCache(cfg.NodeName, storageClient.StorageClient, cfg.MaxDelaySeconds) dWatcher.AddAdaptor(apc) - nnc := networkneighborhoodcache.NewNetworkNeighborhoodCache(nodeName, storageClient.StorageClient, cfg.MaxDelaySeconds) + nnc := networkneighborhoodcache.NewNetworkNeighborhoodCache(cfg.NodeName, storageClient.StorageClient, cfg.MaxDelaySeconds) dWatcher.AddAdaptor(nnc) dc := dnscache.NewDnsCache(dnsResolver) @@ -245,10 +244,10 @@ func main() { objCache = objectcachev1.NewObjectCache(k8sObjectCache, apc, nnc, dc) // create exporter - exporter := exporters.InitExporters(cfg.Exporters, clusterData.ClusterName, nodeName, cloudMetadata) + exporter := exporters.InitExporters(cfg.Exporters, clusterData.ClusterName, cfg.NodeName, cloudMetadata) // create runtimeDetection managers - ruleManager, err = rulemanagerv1.CreateRuleManager(ctx, cfg, k8sClient, ruleBindingCache, objCache, exporter, prometheusExporter, nodeName, clusterData.ClusterName, processManager) + ruleManager, err = rulemanagerv1.CreateRuleManager(ctx, cfg, k8sClient, ruleBindingCache, objCache, exporter, prometheusExporter, cfg.NodeName, clusterData.ClusterName, processManager) if err != nil { logger.L().Ctx(ctx).Fatal("error creating RuleManager", helpers.Error(err)) } @@ -264,7 +263,7 @@ func main() { var profileManager nodeprofilemanager.NodeProfileManagerClient if cfg.EnableNodeProfile { // FIXME validate the HTTPExporterConfig before we use it ? - profileManager = nodeprofilemanagerv1.NewNodeProfileManager(cfg, *clusterData, nodeName, k8sObjectCache, relevancyManager, ruleManager) + profileManager = nodeprofilemanagerv1.NewNodeProfileManager(cfg, *clusterData, cfg.NodeName, k8sObjectCache, relevancyManager, ruleManager) } else { profileManager = nodeprofilemanager.NewNodeProfileManagerMock() } @@ -273,8 +272,8 @@ func main() { var malwareManager malwaremanager.MalwareManagerClient if cfg.EnableMalwareDetection { // create exporter - exporter := exporters.InitExporters(cfg.Exporters, clusterData.ClusterName, nodeName, cloudMetadata) - malwareManager, err = malwaremanagerv1.CreateMalwareManager(cfg, k8sClient, nodeName, clusterData.ClusterName, exporter, prometheusExporter) + exporter := exporters.InitExporters(cfg.Exporters, clusterData.ClusterName, cfg.NodeName, cloudMetadata) + malwareManager, err = malwaremanagerv1.CreateMalwareManager(cfg, k8sClient, cfg.NodeName, clusterData.ClusterName, exporter, prometheusExporter) if err != nil { logger.L().Ctx(ctx).Fatal("error creating MalwareManager", helpers.Error(err)) } @@ -282,8 +281,27 @@ func main() { malwareManager = malwaremanager.CreateMalwareManagerMock() } + // Create the IG k8sClient + igK8sClient, err := containercollection.NewK8sClient(cfg.NodeName) + if err != nil { + logger.L().Fatal("error creating IG Kubernetes client", helpers.Error(err)) + } + defer igK8sClient.Close() + logger.L().Info("IG Kubernetes client created", helpers.Interface("client", igK8sClient)) + + // Create the SBOM manager + var sbomManager sbommanager.SbomManagerClient + if cfg.EnableSbomGeneration { + sbomManager, err = sbommanagerv1.CreateSbomManager(ctx, cfg, igK8sClient.SocketPath, storageClient) + if err != nil { + logger.L().Ctx(ctx).Fatal("error creating SbomManager", helpers.Error(err)) + } + } else { + sbomManager = sbommanager.CreateSbomManagerMock() + } + // Create the container handler - mainHandler, err := containerwatcher.CreateIGContainerWatcher(cfg, applicationProfileManager, k8sClient, relevancyManager, networkManagerClient, dnsManagerClient, prometheusExporter, ruleManager, malwareManager, preRunningContainersIDs, &ruleBindingNotify, containerRuntime, nil, processManager) + mainHandler, err := containerwatcher.CreateIGContainerWatcher(cfg, applicationProfileManager, k8sClient, igK8sClient, relevancyManager, networkManagerClient, dnsManagerClient, prometheusExporter, ruleManager, malwareManager, sbomManager, preRunningContainersIDs, &ruleBindingNotify, containerRuntime, nil, processManager) if err != nil { logger.L().Ctx(ctx).Fatal("error creating the container watcher", helpers.Error(err)) } diff --git a/pkg/config/config.go b/pkg/config/config.go index 6902dfc0..1dff1a92 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,6 +1,7 @@ package config import ( + "os" "slices" "time" @@ -19,6 +20,8 @@ type Config struct { UpdateDataPeriod time.Duration `mapstructure:"updateDataPeriod"` MaxDelaySeconds int `mapstructure:"maxDelaySeconds"` MaxJitterPercentage int `mapstructure:"maxJitterPercentage"` + MaxImageSize int64 `mapstructure:"maxImageSize"` + MaxSBOMSize int `mapstructure:"maxSBOMSize"` EnableFullPathTracing bool `mapstructure:"fullPathTracingEnabled"` EnableApplicationProfile bool `mapstructure:"applicationProfileServiceEnabled"` EnableMalwareDetection bool `mapstructure:"malwareDetectionEnabled"` @@ -32,6 +35,10 @@ type Config struct { EnableSeccomp bool `mapstructure:"seccompServiceEnabled"` ExcludeNamespaces []string `mapstructure:"excludeNamespaces"` IncludeNamespaces []string `mapstructure:"includeNamespaces"` + EnableSbomGeneration bool `mapstructure:"sbomGenerationEnabled"` + NamespaceName string `mapstructure:"namespaceName"` + NodeName string `mapstructure:"nodeName"` + PodName string `mapstructure:"podName"` } // LoadConfig reads configuration from file or environment variables. @@ -45,6 +52,11 @@ func LoadConfig(path string) (Config, error) { viper.SetDefault("nodeProfileInterval", 10*time.Minute) viper.SetDefault("maxDelaySeconds", 30) viper.SetDefault("maxJitterPercentage", 5) + viper.SetDefault("maxImageSize", 5*1024*1024*1024) + viper.SetDefault("maxSBOMSize", 20*1024*1024) + viper.SetDefault("namespaceName", os.Getenv(NamespaceEnvVar)) + viper.SetDefault("nodeName", os.Getenv(NodeNameEnvVar)) + viper.SetDefault("podName", os.Getenv(PodNameEnvVar)) viper.AutomaticEnv() diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index d812a4a8..e0a3831e 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -33,6 +33,8 @@ func TestLoadConfig(t *testing.T) { NodeProfileInterval: 1 * time.Minute, MaxDelaySeconds: 30, MaxJitterPercentage: 5, + MaxImageSize: 5368709120, + MaxSBOMSize: 20971520, EnablePrometheusExporter: true, EnableRuntimeDetection: true, EnableSeccomp: true, diff --git a/pkg/containerwatcher/v1/container_watcher.go b/pkg/containerwatcher/v1/container_watcher.go index 9080d69e..0d9dea79 100644 --- a/pkg/containerwatcher/v1/container_watcher.go +++ b/pkg/containerwatcher/v1/container_watcher.go @@ -3,7 +3,6 @@ package containerwatcher import ( "context" "fmt" - "os" mapset "github.com/deckarep/golang-set/v2" "github.com/goradd/maps" @@ -50,6 +49,7 @@ import ( "github.com/kubescape/node-agent/pkg/relevancymanager" rulebinding "github.com/kubescape/node-agent/pkg/rulebindingmanager" "github.com/kubescape/node-agent/pkg/rulemanager" + "github.com/kubescape/node-agent/pkg/sbommanager" "github.com/kubescape/node-agent/pkg/utils" "github.com/panjf2000/ants/v2" ) @@ -85,18 +85,19 @@ type IGContainerWatcher struct { cfg config.Config containerSelector containercollection.ContainerSelector ctx context.Context - nodeName string podName string namespace string // Clients applicationProfileManager applicationprofilemanager.ApplicationProfileManagerClient + igK8sClient *containercollection.K8sClient k8sClient *k8sinterface.KubernetesApi relevancyManager relevancymanager.RelevancyManagerClient networkManager networkmanager.NetworkManagerClient dnsManager dnsmanager.DNSManagerClient ruleManager rulemanager.RuleManagerClient malwareManager malwaremanager.MalwareManagerClient + sbomManager sbommanager.SbomManagerClient // IG Collections containerCollection *containercollection.ContainerCollection tracerCollection *tracercollection.TracerCollection @@ -160,7 +161,7 @@ type IGContainerWatcher struct { var _ containerwatcher.ContainerWatcher = (*IGContainerWatcher)(nil) -func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager applicationprofilemanager.ApplicationProfileManagerClient, k8sClient *k8sinterface.KubernetesApi, relevancyManager relevancymanager.RelevancyManagerClient, networkManagerClient networkmanager.NetworkManagerClient, dnsManagerClient dnsmanager.DNSManagerClient, metrics metricsmanager.MetricsManager, ruleManager rulemanager.RuleManagerClient, malwareManager malwaremanager.MalwareManagerClient, preRunningContainers mapset.Set[string], ruleBindingPodNotify *chan rulebinding.RuleBindingNotify, runtime *containerutilsTypes.RuntimeConfig, thirdPartyEventReceivers *maps.SafeMap[utils.EventType, mapset.Set[containerwatcher.EventReceiver]], processManager processmanager.ProcessManagerClient) (*IGContainerWatcher, error) { +func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager applicationprofilemanager.ApplicationProfileManagerClient, k8sClient *k8sinterface.KubernetesApi, igK8sClient *containercollection.K8sClient, relevancyManager relevancymanager.RelevancyManagerClient, networkManagerClient networkmanager.NetworkManagerClient, dnsManagerClient dnsmanager.DNSManagerClient, metrics metricsmanager.MetricsManager, ruleManager rulemanager.RuleManagerClient, malwareManager malwaremanager.MalwareManagerClient, sbomManager sbommanager.SbomManagerClient, preRunningContainers mapset.Set[string], ruleBindingPodNotify *chan rulebinding.RuleBindingNotify, runtime *containerutilsTypes.RuntimeConfig, thirdPartyEventReceivers *maps.SafeMap[utils.EventType, mapset.Set[containerwatcher.EventReceiver]], processManager processmanager.ProcessManagerClient) (*IGContainerWatcher, error) { // Use container collection to get notified for new containers containerCollection := &containercollection.ContainerCollection{} // Create a tracer collection instance @@ -421,18 +422,17 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli // Configuration cfg: cfg, containerSelector: containercollection.ContainerSelector{}, // Empty selector to get all containers - nodeName: os.Getenv(config.NodeNameEnvVar), - podName: os.Getenv(config.PodNameEnvVar), - namespace: os.Getenv(config.NamespaceEnvVar), // Clients applicationProfileManager: applicationProfileManager, + igK8sClient: igK8sClient, k8sClient: k8sClient, relevancyManager: relevancyManager, networkManager: networkManagerClient, dnsManager: dnsManagerClient, ruleManager: ruleManager, malwareManager: malwareManager, + sbomManager: sbomManager, // IG Collections containerCollection: containerCollection, tracerCollection: tracerCollection, diff --git a/pkg/containerwatcher/v1/container_watcher_private.go b/pkg/containerwatcher/v1/container_watcher_private.go index 6f641b98..eb3214c7 100644 --- a/pkg/containerwatcher/v1/container_watcher_private.go +++ b/pkg/containerwatcher/v1/container_watcher_private.go @@ -90,6 +90,7 @@ func (ch *IGContainerWatcher) startContainerCollection(ctx context.Context) erro ch.networkManager.ContainerCallback, ch.malwareManager.ContainerCallback, ch.ruleManager.ContainerCallback, + ch.sbomManager.ContainerCallback, ch.processManager.ContainerCallback, } @@ -120,7 +121,7 @@ func (ch *IGContainerWatcher) startContainerCollection(ctx context.Context) erro containercollection.WithTracerCollection(ch.tracerCollection), // Enrich those containers with data from the Kubernetes API - containercollection.WithKubernetesEnrichment(ch.nodeName, ch.k8sClient.K8SConfig), + containercollection.WithKubernetesEnrichment(ch.cfg.NodeName, ch.k8sClient.K8SConfig), } // Initialize the container collection @@ -135,13 +136,8 @@ func (ch *IGContainerWatcher) startContainerCollection(ctx context.Context) erro } func (ch *IGContainerWatcher) startRunningContainers() { - k8sClient, err := containercollection.NewK8sClient(ch.nodeName) - if err != nil { - logger.L().Fatal("creating IG Kubernetes client", helpers.Error(err)) - } - defer k8sClient.Close() for n := range *ch.ruleBindingPodNotify { - ch.addRunningContainers(k8sClient, &n) + ch.addRunningContainers(ch.igK8sClient, &n) } } diff --git a/pkg/containerwatcher/v1/open_test.go b/pkg/containerwatcher/v1/open_test.go index 7fb4e084..fe5ed3cb 100644 --- a/pkg/containerwatcher/v1/open_test.go +++ b/pkg/containerwatcher/v1/open_test.go @@ -4,13 +4,12 @@ import ( "context" "testing" + traceropentype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/open/types" + "github.com/inspektor-gadget/inspektor-gadget/pkg/types" "github.com/kubescape/node-agent/pkg/config" "github.com/kubescape/node-agent/pkg/filehandler/v1" "github.com/kubescape/node-agent/pkg/metricsmanager" "github.com/kubescape/node-agent/pkg/relevancymanager/v1" - - traceropentype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/open/types" - "github.com/inspektor-gadget/inspektor-gadget/pkg/types" "github.com/stretchr/testify/assert" ) @@ -23,7 +22,7 @@ func BenchmarkIGContainerWatcher_openEventCallback(b *testing.B) { assert.NoError(b, err) mockExporter := metricsmanager.NewMetricsMock() - mainHandler, err := CreateIGContainerWatcher(cfg, nil, nil, relevancyManager, nil, nil, mockExporter, nil, nil, nil, nil, nil, nil, nil) + mainHandler, err := CreateIGContainerWatcher(cfg, nil, nil, nil, relevancyManager, nil, nil, mockExporter, nil, nil, nil, nil, nil, nil, nil, nil) assert.NoError(b, err) event := &traceropentype.Event{ Event: types.Event{ diff --git a/pkg/filehandler/v1/inmemory.go b/pkg/filehandler/v1/inmemory.go index ea282132..e8179b3a 100644 --- a/pkg/filehandler/v1/inmemory.go +++ b/pkg/filehandler/v1/inmemory.go @@ -4,6 +4,8 @@ import ( "fmt" "sync" + "github.com/kubescape/go-logger" + "github.com/kubescape/go-logger/helpers" "github.com/kubescape/node-agent/pkg/filehandler" ) @@ -45,6 +47,7 @@ func (s *InMemoryFileHandler) AddFile(bucket, file string) { files: make(map[string]bool, initFileListLength), } s.buckets[bucket] = bucketFiles + logger.L().Debug("Created new bucket", helpers.String("bucket", bucket)) } s.mutex.Unlock() } @@ -109,6 +112,7 @@ func (s *InMemoryFileHandler) AddFiles(bucket string, files map[string]bool) err files: make(map[string]bool, initFileListLength), } s.buckets[bucket] = bucketFiles + logger.L().Debug("Created new bucket", helpers.String("bucket", bucket)) } s.mutex.Unlock() } diff --git a/pkg/relevancymanager/v1/relevancy_manager.go b/pkg/relevancymanager/v1/relevancy_manager.go index cf01495a..3949f4f8 100644 --- a/pkg/relevancymanager/v1/relevancy_manager.go +++ b/pkg/relevancymanager/v1/relevancy_manager.go @@ -6,17 +6,9 @@ import ( "fmt" "time" - "github.com/kubescape/node-agent/pkg/config" - "github.com/kubescape/node-agent/pkg/filehandler" - "github.com/kubescape/node-agent/pkg/k8sclient" - "github.com/kubescape/node-agent/pkg/relevancymanager" - "github.com/kubescape/node-agent/pkg/sbomhandler" - "github.com/kubescape/node-agent/pkg/utils" - + "github.com/armosec/utils-k8s-go/wlid" "github.com/cenkalti/backoff/v4" mapset "github.com/deckarep/golang-set/v2" - - "github.com/armosec/utils-k8s-go/wlid" "github.com/goradd/maps" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" "github.com/kubescape/go-logger" @@ -24,6 +16,12 @@ import ( "github.com/kubescape/k8s-interface/instanceidhandler" instanceidhandlerV1 "github.com/kubescape/k8s-interface/instanceidhandler/v1" "github.com/kubescape/k8s-interface/workloadinterface" + "github.com/kubescape/node-agent/pkg/config" + "github.com/kubescape/node-agent/pkg/filehandler" + "github.com/kubescape/node-agent/pkg/k8sclient" + "github.com/kubescape/node-agent/pkg/relevancymanager" + "github.com/kubescape/node-agent/pkg/sbomhandler" + "github.com/kubescape/node-agent/pkg/utils" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" @@ -69,13 +67,11 @@ func (rm *RelevancyManager) deleteResources(watchedContainer *utils.WatchedConta func (rm *RelevancyManager) ensureImageInfo(container *containercollection.Container, watchedContainer *utils.WatchedContainerData) error { - if watchedContainer.ImageID == "" || watchedContainer.ImageTag == "" || watchedContainer.InstanceID == nil || watchedContainer.Wlid == "" { - imageID, imageTag, parentWlid, parentResourceVersion, podTemplateHash, instanceID, err := rm.getContainerInfo(watchedContainer, container.K8s.Namespace, container.K8s.PodName, container.K8s.ContainerName) + if watchedContainer.InstanceID == nil || watchedContainer.Wlid == "" { + parentWlid, parentResourceVersion, podTemplateHash, instanceID, err := rm.getContainerInfo(watchedContainer, container.K8s.Namespace, container.K8s.PodName, container.K8s.ContainerName) if err != nil { return fmt.Errorf("failed to get image info: %v", err) } - watchedContainer.ImageID = imageID - watchedContainer.ImageTag = imageTag watchedContainer.InstanceID = instanceID watchedContainer.Wlid = parentWlid watchedContainer.ParentResourceVersion = parentResourceVersion @@ -85,9 +81,7 @@ func (rm *RelevancyManager) ensureImageInfo(container *containercollection.Conta return nil } -func (rm *RelevancyManager) getContainerInfo(watchedContainer *utils.WatchedContainerData, namespace, podName, containerName string) (string, string, string, string, string, instanceidhandler.IInstanceID, error) { - imageID := "" - imageTag := "" +func (rm *RelevancyManager) getContainerInfo(watchedContainer *utils.WatchedContainerData, namespace, podName, containerName string) (string, string, string, instanceidhandler.IInstanceID, error) { parentWlid := "" parentResourceVersion := "" podTemplateHash := "" @@ -95,7 +89,7 @@ func (rm *RelevancyManager) getContainerInfo(watchedContainer *utils.WatchedCont var instanceID instanceidhandler.IInstanceID wl, err := rm.k8sClient.GetWorkload(namespace, "Pod", podName) if err != nil { - return imageID, imageTag, parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("fail to get pod %s in namespace %s with error: %v", podName, namespace, err) + return parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("fail to get pod %s in namespace %s with error: %v", podName, namespace, err) } pod := wl.(*workloadinterface.Workload) @@ -107,41 +101,24 @@ func (rm *RelevancyManager) getContainerInfo(watchedContainer *utils.WatchedCont // find parentWlid kind, name, err := rm.k8sClient.CalculateWorkloadParentRecursive(pod) if err != nil { - return imageID, imageTag, parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("fail to get workload owner parent %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) + return parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("fail to get workload owner parent %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) } parentWorkload, err := rm.k8sClient.GetWorkload(pod.GetNamespace(), kind, name) if err != nil { - return imageID, imageTag, parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("fail to get parent workload %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) + return parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("fail to get parent workload %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) } w := parentWorkload.(*workloadinterface.Workload) parentWlid = w.GenerateWlid(rm.clusterName) parentResourceVersion = w.GetResourceVersion() err = wlid.IsWlidValid(parentWlid) if err != nil { - return imageID, imageTag, parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("WLID of parent workload is not in the right %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) - } - - imageTag, err = findImageTag(pod, containerName, watchedContainer.ContainerType) - if err != nil { - return imageID, imageTag, parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("fail to get containers for pod %s in namespace %s with error: %v", podName, namespace, err) - } - if imageTag == "" { - return imageID, imageTag, parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("failed to find container %s in pod %s in namespace %s", containerName, podName, namespace) - } - - // find imageID - imageID, err = findImageID(pod, containerName, watchedContainer.ContainerType) - if err != nil { - return imageID, imageTag, parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("fail to get containers for pod %s in namespace %s with error: %v", podName, namespace, err) - } - if imageID == "" { - return imageID, imageTag, parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("failed to find container status %s in pod %s in namespace %s", containerName, podName, namespace) + return parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("WLID of parent workload is not in the right %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) } // find instanceID instanceIDs, err := instanceidhandlerV1.GenerateInstanceID(pod) if err != nil { - return imageID, imageTag, parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("fail to create InstanceID to pod %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) + return parentWlid, parentResourceVersion, podTemplateHash, instanceID, fmt.Errorf("fail to create InstanceID to pod %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) } instanceID = instanceIDs[0] for i := range instanceIDs { @@ -152,7 +129,7 @@ func (rm *RelevancyManager) getContainerInfo(watchedContainer *utils.WatchedCont instanceID = instanceIDs[i] } } - return imageID, imageTag, parentWlid, parentResourceVersion, podTemplateHash, instanceID, nil + return parentWlid, parentResourceVersion, podTemplateHash, instanceID, nil } // Handle relevant data @@ -180,72 +157,6 @@ func (rm *RelevancyManager) handleRelevancy(ctx context.Context, watchedContaine span.End() } -func findImageID(pod workloadinterface.IWorkload, containerName string, containerType utils.ContainerType) (string, error) { - var containerStatuses []v1.ContainerStatus - // find imageID - podStatus, err := pod.GetPodStatus() // Careful this is not available on container creation - if err != nil { - return "", err - } - switch containerType { - case utils.Container: - containerStatuses = podStatus.ContainerStatuses - case utils.InitContainer: - containerStatuses = podStatus.InitContainerStatuses - case utils.EphemeralContainer: - containerStatuses = podStatus.EphemeralContainerStatuses - default: - // noop - } - - for i := range containerStatuses { - if containerStatuses[i].Name == containerName { - return containerStatuses[i].ImageID, nil - } - } - return "", nil - -} - -func findImageTag(pod workloadinterface.IWorkload, containerName string, containerType utils.ContainerType) (string, error) { - var containers []v1.Container - var ephemeralContainers []v1.EphemeralContainer - var err error - - switch containerType { - case utils.Container: - containers, err = pod.GetContainers() - if err != nil { - return "", err - } - case utils.InitContainer: - containers, err = pod.GetInitContainers() - if err != nil { - return "", err - } - case utils.EphemeralContainer: - ephemeralContainers, err = pod.GetEphemeralContainers() - if err != nil { - return "", err - } - default: - // noop - - } - for i := range containers { - if containers[i].Name == containerName { - return containers[i].Image, nil - } - } - for i := range ephemeralContainers { - if ephemeralContainers[i].Name == containerName { - return ephemeralContainers[i].Image, nil - } - } - - return "", nil - -} func (rm *RelevancyManager) monitorContainer(ctx context.Context, container *containercollection.Container, watchedContainer *utils.WatchedContainerData) error { for { select { @@ -272,6 +183,7 @@ func (rm *RelevancyManager) monitorContainer(ctx context.Context, container *con } } } + func (rm *RelevancyManager) ContainerReachedMaxTime(containerID string) { if channel := rm.watchedContainerChannels.Get(containerID); channel != nil { channel <- utils.ContainerReachedMaxTime @@ -282,6 +194,8 @@ func (rm *RelevancyManager) startRelevancyProcess(ctx context.Context, container ctx, span := otel.Tracer("").Start(ctx, "RelevancyManager.startRelevancyProcess") defer span.End() + logger.L().Info("RelevancyManager - start monitor on container", helpers.String("container ID", container.Runtime.ContainerID), helpers.String("k8s workload", k8sContainerID)) + watchedContainer := &utils.WatchedContainerData{ ContainerID: container.Runtime.ContainerID, ImageID: container.Runtime.ContainerImageDigest, diff --git a/pkg/relevancymanager/v1/relevancy_manager_test.go b/pkg/relevancymanager/v1/relevancy_manager_test.go index 51231a61..d2c2a6e0 100644 --- a/pkg/relevancymanager/v1/relevancy_manager_test.go +++ b/pkg/relevancymanager/v1/relevancy_manager_test.go @@ -7,22 +7,19 @@ import ( "os" "path" "testing" + "time" + mapset "github.com/deckarep/golang-set/v2" + containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" + "github.com/inspektor-gadget/inspektor-gadget/pkg/types" + "github.com/kinbiko/jsonassert" + helpersv1 "github.com/kubescape/k8s-interface/instanceidhandler/v1/helpers" "github.com/kubescape/node-agent/pkg/config" "github.com/kubescape/node-agent/pkg/filehandler/v1" "github.com/kubescape/node-agent/pkg/k8sclient" "github.com/kubescape/node-agent/pkg/sbomhandler/syfthandler" "github.com/kubescape/node-agent/pkg/storage" "github.com/kubescape/node-agent/pkg/utils" - - mapset "github.com/deckarep/golang-set/v2" - helpersv1 "github.com/kubescape/k8s-interface/instanceidhandler/v1/helpers" - - "time" - - containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" - "github.com/inspektor-gadget/inspektor-gadget/pkg/types" - "github.com/kinbiko/jsonassert" "github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1" "github.com/stretchr/testify/assert" ) @@ -76,7 +73,9 @@ func TestRelevancyManager(t *testing.T) { }, Runtime: containercollection.RuntimeMetadata{ BasicRuntimeMetadata: types.BasicRuntimeMetadata{ - ContainerID: "5fff6a395ce4e6984a9447cc6cfb09f473eaf278498243963fcc944889bc8400", + ContainerID: "5fff6a395ce4e6984a9447cc6cfb09f473eaf278498243963fcc944889bc8400", + ContainerImageDigest: "nginx@sha256:6a59f1cbb8d28ac484176d52c473494859a512ddba3ea62a547258cf16c9b3ae", + ContainerImageName: "nginx", }, }, } @@ -180,7 +179,9 @@ func TestRelevancyManagerIncompleteSBOM(t *testing.T) { }, Runtime: containercollection.RuntimeMetadata{ BasicRuntimeMetadata: types.BasicRuntimeMetadata{ - ContainerID: "5fff6a395ce4e6984a9447cc6cfb09f473eaf278498243963fcc944889bc8400", + ContainerID: "5fff6a395ce4e6984a9447cc6cfb09f473eaf278498243963fcc944889bc8400", + ContainerImageName: "docker.io/library/nginx:latest", + ContainerImageDigest: "sha256:0c86dddac19f2ce4fd716ac58c0fd87bf69bfd4edabfd6971fb885bafd12a00b", }, }, } diff --git a/pkg/sbommanager/sbom_manager_interface.go b/pkg/sbommanager/sbom_manager_interface.go new file mode 100644 index 00000000..97024ac8 --- /dev/null +++ b/pkg/sbommanager/sbom_manager_interface.go @@ -0,0 +1,7 @@ +package sbommanager + +import containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" + +type SbomManagerClient interface { + ContainerCallback(notif containercollection.PubSubEvent) +} diff --git a/pkg/sbommanager/sbom_manager_mock.go b/pkg/sbommanager/sbom_manager_mock.go new file mode 100644 index 00000000..713804f2 --- /dev/null +++ b/pkg/sbommanager/sbom_manager_mock.go @@ -0,0 +1,15 @@ +package sbommanager + +import containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" + +type SbomManagerMock struct{} + +var _ SbomManagerClient = (*SbomManagerMock)(nil) + +func CreateSbomManagerMock() *SbomManagerMock { + return &SbomManagerMock{} +} + +func (s SbomManagerMock) ContainerCallback(_ containercollection.PubSubEvent) { + // noop +} diff --git a/pkg/sbommanager/v1/resolver.go b/pkg/sbommanager/v1/resolver.go new file mode 100644 index 00000000..9d376980 --- /dev/null +++ b/pkg/sbommanager/v1/resolver.go @@ -0,0 +1,162 @@ +package v1 + +import ( + "context" + "fmt" + "io" + "os" + "sync" + + "github.com/anchore/syft/syft/file" + "github.com/anchore/syft/syft/source" + "github.com/anchore/syft/syft/source/directorysource" + mapset "github.com/deckarep/golang-set/v2" + imagedigest "github.com/opencontainers/go-digest" +) + +type NodeResolver struct { + layers []imagedigest.Digest + resolvers []file.Resolver +} + +var _ file.Resolver = (*NodeResolver)(nil) + +func NewResolver(scope source.Scope, layers []imagedigest.Digest, mounts []string) (*NodeResolver, error) { + resolvers := make([]file.Resolver, len(mounts)) + for i, path := range mounts { + directorySource, err := directorysource.New(directorysource.Config{ + Path: path, + Base: path, + }) + if err != nil { + return nil, fmt.Errorf("unable to create directory source: %w", err) + } + resolver, _ := directorySource.FileResolver(scope) + resolvers[i] = resolver + } + return &NodeResolver{ + layers: layers, + resolvers: resolvers, + }, nil +} + +func (n NodeResolver) FileContentsByLocation(location file.Location) (io.ReadCloser, error) { + for _, resolver := range n.resolvers { + reader, err := resolver.FileContentsByLocation(location) + if err == nil { + return reader, nil + } + } + return nil, os.ErrNotExist +} + +func (n NodeResolver) HasPath(s string) bool { + for _, resolver := range n.resolvers { + if resolver.HasPath(s) { + return true + } + } + return false +} + +func (n NodeResolver) FilesByPath(paths ...string) ([]file.Location, error) { + var allLocations = make([]file.Location, 0) + added := mapset.NewThreadUnsafeSet[string]() + for i, resolver := range n.resolvers { + locations, _ := resolver.FilesByPath(paths...) + if len(locations) > 0 { + for _, location := range locations { + if added.Contains(location.LocationData.AccessPath) { + continue + } + location.LocationData.Coordinates.FileSystemID = n.layers[i].String() + allLocations = append(allLocations, location) + added.Add(location.LocationData.AccessPath) + } + } + } + return allLocations, nil +} + +func (n NodeResolver) FilesByGlob(patterns ...string) ([]file.Location, error) { + var allLocations = make([]file.Location, 0) + added := mapset.NewThreadUnsafeSet[string]() + for i, resolver := range n.resolvers { + locations, _ := resolver.FilesByGlob(patterns...) + if len(locations) > 0 { + for _, location := range locations { + if added.Contains(location.LocationData.AccessPath) { + continue + } + location.LocationData.Coordinates.FileSystemID = n.layers[i].String() + allLocations = append(allLocations, location) + added.Add(location.LocationData.AccessPath) + } + } + } + return allLocations, nil +} + +func (n NodeResolver) FilesByMIMEType(types ...string) ([]file.Location, error) { + var allLocations = make([]file.Location, 0) + added := mapset.NewThreadUnsafeSet[string]() + for i, resolver := range n.resolvers { + locations, _ := resolver.FilesByMIMEType(types...) + if len(locations) > 0 { + for _, location := range locations { + if added.Contains(location.LocationData.AccessPath) { + continue + } + location.LocationData.Coordinates.FileSystemID = n.layers[i].String() + allLocations = append(allLocations, location) + added.Add(location.LocationData.AccessPath) + } + } + } + return allLocations, nil +} + +func (n NodeResolver) RelativeFileByPath(_ file.Location, path string) *file.Location { + for i, resolver := range n.resolvers { + location := resolver.RelativeFileByPath(file.Location{}, path) + if location != nil { + location.LocationData.Coordinates.FileSystemID = n.layers[i].String() + return location + } + } + return nil +} + +func (n NodeResolver) AllLocations(ctx context.Context) <-chan file.Location { + results := make(chan file.Location) + var wg sync.WaitGroup + for _, resolver := range n.resolvers { + wg.Add(1) + go func(locations <-chan file.Location) { + defer wg.Done() + for location := range locations { + select { + case <-ctx.Done(): + return + case results <- location: + continue + } + } + }(resolver.AllLocations(ctx)) + } + go func() { + wg.Wait() + close(results) + }() + return results +} + +func (n NodeResolver) FileMetadataByLocation(location file.Location) (file.Metadata, error) { + for _, resolver := range n.resolvers { + metadata, err := resolver.FileMetadataByLocation(location) + if err == nil { + return metadata, nil + } + } + return file.Metadata{}, os.ErrNotExist +} diff --git a/pkg/sbommanager/v1/sbom_manager.go b/pkg/sbommanager/v1/sbom_manager.go new file mode 100644 index 00000000..2771aeb5 --- /dev/null +++ b/pkg/sbommanager/v1/sbom_manager.go @@ -0,0 +1,681 @@ +package v1 + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net" + "os" + "path/filepath" + "regexp" + "runtime/debug" + "strconv" + "strings" + "time" + + "github.com/DmitriyVTitov/size" + "github.com/anchore/syft/syft" + "github.com/anchore/syft/syft/file" + "github.com/anchore/syft/syft/format" + "github.com/anchore/syft/syft/format/syftjson" + "github.com/anchore/syft/syft/format/syftjson/model" + "github.com/anchore/syft/syft/sbom" + "github.com/aquilax/truncate" + securejoin "github.com/cyphar/filepath-securejoin" + mapset "github.com/deckarep/golang-set/v2" + "github.com/distribution/distribution/reference" + "github.com/gammazero/workerpool" + "github.com/google/go-containerregistry/pkg/name" + containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" + "github.com/kubescape/go-logger" + "github.com/kubescape/go-logger/helpers" + helpersv1 "github.com/kubescape/k8s-interface/instanceidhandler/v1/helpers" + "github.com/kubescape/k8s-interface/names" + "github.com/kubescape/node-agent/pkg/config" + "github.com/kubescape/node-agent/pkg/sbommanager" + "github.com/kubescape/node-agent/pkg/storage" + "github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1" + "github.com/moby/sys/mountinfo" + "github.com/opencontainers/go-digest" + "github.com/spf13/afero" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/validation" + runtime "k8s.io/cri-api/pkg/apis/runtime/v1" +) + +const ( + digestDelim = "@" + NodeNameMetadataKey = "kubescape.io/node-name" + ToolVersionMetadataKey = "kubescape.io/tool-version" +) + +type SbomManager struct { + appFs afero.Fs + cfg config.Config + ctx context.Context + hostRoot string + imageServiceClient runtime.ImageServiceClient + pool *workerpool.WorkerPool + procDir string + processing mapset.Set[string] + storageClient storage.StorageClient + version string +} + +var _ sbommanager.SbomManagerClient = (*SbomManager)(nil) + +func CreateSbomManager(ctx context.Context, cfg config.Config, socketPath string, storageClient storage.StorageClient) (*SbomManager, error) { + // read HOST_ROOT from env + hostRoot, exists := os.LookupEnv("HOST_ROOT") + if !exists { + hostRoot = "/host" + } + // use securejoin to join the two, add proc and store in procDir + procDir, err := securejoin.SecureJoin(hostRoot, "/proc") + if err != nil { + return nil, fmt.Errorf("failed to get proc dir: %w", err) + } + // connect to CRI socket + conn, _ := grpc.Dial( + socketPath, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) { + d := net.Dialer{Timeout: 2 * time.Second} + return d.DialContext(ctx, "unix", socketPath) + }), + ) + return &SbomManager{ + appFs: afero.NewOsFs(), + cfg: cfg, + ctx: ctx, + hostRoot: hostRoot, + imageServiceClient: runtime.NewImageServiceClient(conn), + pool: workerpool.New(1), + procDir: procDir, + processing: mapset.NewSet[string](), + storageClient: storageClient, + version: packageVersion("github.com/anchore/syft"), + }, nil +} + +func (s *SbomManager) getImageStatus(imageID string) (*runtime.ImageStatusResponse, error) { + return s.imageServiceClient.ImageStatus(context.Background(), &runtime.ImageStatusRequest{ + Image: &runtime.ImageSpec{Image: imageID}, + Verbose: true, + }) +} + +func (s *SbomManager) getMountedVolumes(pid string) ([]string, error) { + f, err := s.appFs.Open(filepath.Join(s.procDir, pid, "mountinfo")) + if err != nil { + return nil, fmt.Errorf("failed to open /proc/%s/mountinfo: %w", pid, err) + } + defer func() { + _ = f.Close() + }() + mounts, err := mountinfo.GetMountsFromReader(f, func(info *mountinfo.Info) (skip, stop bool) { + if info.FSType == "overlay" { + return false, true + } + return true, false + }) + if err != nil { + return nil, fmt.Errorf("failed to get mounts: %w", err) + } + for _, option := range strings.Split(mounts[0].VFSOptions, ",") { + if strings.HasPrefix(option, "lowerdir=") { + var volumes []string + for _, volume := range strings.Split(option[9:], ":") { + // FIXME this is a workaround + if !strings.HasPrefix(volume, "/") { + volume = "/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/" + volume + } + volumes = append(volumes, filepath.Join(s.hostRoot, volume)) + } + return volumes, nil + } + } + return nil, fmt.Errorf("failed to find lowerdir in %s", mounts[0].VFSOptions) +} + +func (s *SbomManager) ContainerCallback(notif containercollection.PubSubEvent) { + // only consider container start events + if notif.Type != containercollection.EventTypeAddContainer { + return + } + // check if the container should be ignored + if s.cfg.SkipNamespace(notif.Container.K8s.Namespace) { + return + } + // enqueue the container for processing + s.pool.Submit(func() { + s.processContainer(notif) + }) +} + +func (s *SbomManager) processContainer(notif containercollection.PubSubEvent) { + // prepare SBOM name + // ContainerImageDigest is containerStatuses[0].image (not imageID) + sbomName, err := names.ImageInfoToSlug(notif.Container.Runtime.ContainerImageName, notif.Container.Runtime.ContainerImageDigest) + if err != nil { + logger.L().Ctx(s.ctx).Error("SbomManager - failed to generate SBOM name", + helpers.Error(err), + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest)) + return + } + // try to create a SBOM with initializing status to reserve our slot + imageID := normalizeImageID(notif.Container.Runtime.ContainerImageName, notif.Container.Runtime.ContainerImageDigest) + wipSbom := &v1beta1.SBOMSyft{ + ObjectMeta: metav1.ObjectMeta{ + Name: sbomName, + Annotations: map[string]string{ + helpersv1.ImageIDMetadataKey: imageID, + helpersv1.ImageTagMetadataKey: notif.Container.Runtime.ContainerImageName, + helpersv1.StatusMetadataKey: helpersv1.Initializing, + NodeNameMetadataKey: s.cfg.NodeName, + ToolVersionMetadataKey: s.version, + }, + Labels: labelsFromImageID(imageID), + }, + } + wipSbom, err = s.storageClient.CreateSBOM(wipSbom) + switch { + case k8serrors.IsAlreadyExists(err): + // get the existing SBOM metadata and check if it is ready or being processed by another node + // wipSbom is empty because of the error so we can reuse the pointer + wipSbom, err = s.storageClient.GetSBOMMeta(sbomName) + if err != nil { + logger.L().Ctx(s.ctx).Error("SbomManager - failed to get existing SBOM metadata", + helpers.Error(err), + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName)) + return + } + switch { + case wipSbom.Annotations[helpersv1.StatusMetadataKey] == helpersv1.TooLarge: + logger.L().Debug("SbomManager - image is too large for SBOM processing, skipping", + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName), + helpers.String("nodeName", wipSbom.Annotations[NodeNameMetadataKey])) + return + case wipSbom.Annotations[helpersv1.StatusMetadataKey] == helpersv1.Ready: + // only skip if the SBOM was created with the same version of tool + if wipSbom.Annotations[ToolVersionMetadataKey] == s.version { + logger.L().Debug("SbomManager - SBOM is already created, skipping", + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName)) + return + } + logger.L().Debug("SbomManager - SBOM was created with an different version of tool, recreating it", + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName), + helpers.String("got version", wipSbom.Annotations[ToolVersionMetadataKey]), + helpers.String("expected version", s.version)) + // update the version of the tool + wipSbom.Annotations[ToolVersionMetadataKey] = s.version + // continue to create SBOM + case wipSbom.Annotations[NodeNameMetadataKey] != s.cfg.NodeName: + logger.L().Debug("SbomManager - SBOM is already being processed by another node, skipping", + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName), + helpers.String("nodeName", wipSbom.Annotations[NodeNameMetadataKey])) + return + case s.processing.Contains(sbomName): + logger.L().Debug("SbomManager - SBOM is already being processed by this node, skipping", + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName)) + return + default: + logger.L().Debug("SbomManager - SBOM processing was interrupted, retrying", + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName)) + // continue to create SBOM + } + case err != nil: + logger.L().Ctx(s.ctx).Error("SbomManager - failed to create empty SBOM before processing", + helpers.Error(err), + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName)) + return + default: + logger.L().Debug("SbomManager - created empty SBOM, start processing", + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName)) + // continue to create SBOM + } + // track SBOM as processing in internal state to prevent concurrent processing + s.processing.Add(sbomName) + defer s.processing.Remove(sbomName) + // get container mounts + pid := strconv.Itoa(int(notif.Container.Pid)) + mounts, err := s.getMountedVolumes(pid) + if err != nil { + logger.L().Ctx(s.ctx).Error("SbomManager - failed to get mounted volumes", + helpers.Error(err), + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName)) + return + } + // get image layers + imageStatus, err := s.getImageStatus(notif.Container.Runtime.ContainerImageName) + if err != nil { + logger.L().Ctx(s.ctx).Error("SbomManager - failed to get image layers", + helpers.Error(err), + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName)) + return + } + // prepare image source + src, err := NewSource(notif.Container.Runtime.ContainerImageName, notif.Container.Runtime.ContainerImageDigest, imageID, imageStatus, mounts, s.cfg.MaxImageSize) + if err != nil { + logger.L().Ctx(s.ctx).Error("SbomManager - failed to create image source", + helpers.Error(err), + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName)) + if errors.Is(err, ErrImageTooLarge) { + delete(wipSbom.Annotations, NodeNameMetadataKey) + wipSbom.Annotations[helpersv1.StatusMetadataKey] = helpersv1.TooLarge + _, _ = s.storageClient.ReplaceSBOM(wipSbom) + } + return + } + // create the SBOM + cfg := syft.DefaultCreateSBOMConfig() + cfg.ToolName = "syft" + cfg.ToolVersion = s.version + syftSBOM, err := syft.CreateSBOM(context.Background(), src, cfg) + if err != nil { + logger.L().Ctx(s.ctx).Error("SbomManager - failed to generate SBOM", + helpers.Error(err), + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName)) + // TODO we could save the error in a status field + return + } + // prepare the SBOM + delete(wipSbom.Annotations, NodeNameMetadataKey) + wipSbom.Spec.Metadata.Report.CreatedAt = wipSbom.CreationTimestamp + wipSbom.Spec.Metadata.Tool.Name = "syft" + wipSbom.Spec.Metadata.Tool.Version = s.version + wipSbom.Spec.Syft = toSyftDocument(syftSBOM) + // check the size of the SBOM + sz := size.Of(wipSbom) + wipSbom.Annotations[helpersv1.ResourceSizeMetadataKey] = fmt.Sprintf("%d", sz) + if sz > s.cfg.MaxSBOMSize { + logger.L().Ctx(s.ctx).Warning("SbomManager - SBOM exceeds size limit", + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName), + helpers.Int("maxImageSize", s.cfg.MaxSBOMSize), + helpers.Int("size", sz)) + wipSbom.Annotations[helpersv1.StatusMetadataKey] = helpersv1.TooLarge + } else { + wipSbom.Annotations[helpersv1.StatusMetadataKey] = helpersv1.Ready + } + // save the SBOM + _, err = s.storageClient.ReplaceSBOM(wipSbom) + if err != nil { + logger.L().Ctx(s.ctx).Error("SbomManager - failed to save SBOM", + helpers.Error(err), + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName)) + return + } + logger.L().Debug("SbomManager - saved SBOM after successful processing", + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("imageName", notif.Container.Runtime.ContainerImageName), + helpers.String("imageDigest", notif.Container.Runtime.ContainerImageDigest), + helpers.String("sbomName", sbomName)) +} + +func formatSBOM(s sbom.SBOM) ([]byte, error) { + bytes, err := format.Encode(s, syftjson.NewFormatEncoder()) + if err != nil { + return nil, fmt.Errorf("failed to encode SBOM: %w", err) + } + return bytes, nil +} + +func labelsFromImageID(imageID string) map[string]string { + labels := map[string]string{} + ref, err := reference.Parse(imageID) + if err != nil { + return labels + } + if named, ok := ref.(reference.Named); ok { + labels[helpersv1.ImageIDMetadataKey] = sanitize(named.String()) + labels[helpersv1.ImageNameMetadataKey] = sanitize(named.Name()) + } + if tagged, ok := ref.(reference.Tagged); ok { + labels[helpersv1.ImageTagMetadataKey] = sanitize(tagged.Tag()) + } + // prune invalid labels + for key, value := range labels { + if errs := validation.IsDNS1123Label(value); len(errs) != 0 { + delete(labels, key) + } + } + return labels +} + +func normalizeImageID(imageName, imageDigest string) string { + // registry scanning doesn't provide imageID, so we use imageTag as a reference + if imageDigest == "" { + return imageName + } + + // try to parse imageID as a full digest + if newDigest, err := name.NewDigest(imageDigest); err == nil { + return newDigest.String() + } + // if it's not a full digest, we need to use imageTag as a reference + tag, err := name.ParseReference(imageName) + if err != nil { + return "" + } + + // and append imageID as a digest + parts := strings.Split(imageDigest, digestDelim) + // filter garbage + if len(parts) > 1 { + imageDigest = parts[len(parts)-1] + } + prefix := digest.Canonical.String() + ":" + if !strings.HasPrefix(imageDigest, prefix) { + // add missing prefix + imageDigest = prefix + imageDigest + } + // docker.io is parsed as index.docker.io + normalizedImageName := strings.Replace(tag.Context().String(), "index.docker.io", "docker.io", 1) + return normalizedImageName + digestDelim + imageDigest +} + +func packageVersion(name string) string { + bi, ok := debug.ReadBuildInfo() + if ok { + for _, dep := range bi.Deps { + if dep.Path == name { + return dep.Version + } + } + } + return "unknown" +} + +var offendingChars = regexp.MustCompile("[@:/ ._]") + +func sanitize(s string) string { + s2 := truncate.Truncate(offendingChars.ReplaceAllString(s, "-"), 63, "", truncate.PositionEnd) + // remove trailing dash + if len(s2) > 0 && s2[len(s2)-1] == '-' { + return s2[:len(s2)-1] + } + return s2 +} + +func toCPEs(c []model.CPE) v1beta1.CPEs { + cpes := make(v1beta1.CPEs, len(c)) + for i := range c { + cpes[i] = v1beta1.CPE(c[i]) + } + return cpes +} + +func toDigests(d []file.Digest) []v1beta1.Digest { + digests := make([]v1beta1.Digest, len(d)) + for i := range d { + digests[i].Algorithm = d[i].Algorithm + digests[i].Value = d[i].Value + } + return digests +} + +func toELFSecurityFeatures(f *file.ELFSecurityFeatures) *v1beta1.ELFSecurityFeatures { + if f == nil { + return nil + } + return &v1beta1.ELFSecurityFeatures{ + SymbolTableStripped: f.SymbolTableStripped, + StackCanary: f.StackCanary, + NoExecutable: f.NoExecutable, + RelocationReadOnly: v1beta1.RelocationReadOnly(f.RelocationReadOnly), + PositionIndependentExecutable: f.PositionIndependentExecutable, + DynamicSharedObject: f.DynamicSharedObject, + LlvmSafeStack: f.LlvmSafeStack, + LlvmControlFlowIntegrity: f.LlvmControlFlowIntegrity, + ClangFortifySource: f.ClangFortifySource, + } +} + +func toExecutable(e *file.Executable) *v1beta1.Executable { + if e == nil { + return nil + } + return &v1beta1.Executable{ + Format: v1beta1.ExecutableFormat(e.Format), + HasExports: e.HasExports, + HasEntrypoint: e.HasEntrypoint, + ImportedLibraries: e.ImportedLibraries, + ELFSecurityFeatures: toELFSecurityFeatures(e.ELFSecurityFeatures), + } +} + +func toFileLicenseEvidence(e *model.FileLicenseEvidence) *v1beta1.FileLicenseEvidence { + if e == nil { + return nil + } + return &v1beta1.FileLicenseEvidence{ + Confidence: int64(e.Confidence), + Offset: int64(e.Offset), + Extent: int64(e.Extent), + } +} + +func toFileLicenses(l []model.FileLicense) []v1beta1.FileLicense { + licenses := make([]v1beta1.FileLicense, len(l)) + for i := range l { + licenses[i].Value = l[i].Value + licenses[i].SPDXExpression = l[i].SPDXExpression + licenses[i].Type = v1beta1.LicenseType(l[i].Type) + licenses[i].Evidence = toFileLicenseEvidence(l[i].Evidence) + } + return licenses +} + +func toFileMetadataEntry(m *model.FileMetadataEntry) *v1beta1.FileMetadataEntry { + if m == nil { + return nil + } + return &v1beta1.FileMetadataEntry{ + Mode: int64(m.Mode), + Type: m.Type, + LinkDestination: m.LinkDestination, + UserID: int64(m.UserID), + GroupID: int64(m.GroupID), + MIMEType: m.MIMEType, + Size_: m.Size, + } +} + +func toLicenses(l []model.License) v1beta1.Licenses { + licenses := make(v1beta1.Licenses, len(l)) + for i := range l { + licenses[i].Value = l[i].Value + licenses[i].SPDXExpression = l[i].SPDXExpression + licenses[i].Type = v1beta1.LicenseType(l[i].Type) + licenses[i].URLs = l[i].URLs + licenses[i].Locations = toLocations(l[i].Locations) + } + return licenses +} + +func toLocations(l []file.Location) []v1beta1.Location { + locations := make([]v1beta1.Location, len(l)) + for i := range l { + locations[i].Coordinates = v1beta1.Coordinates(l[i].Coordinates) + locations[i].VirtualPath = l[i].AccessPath + locations[i].RealPath = l[i].RealPath + locations[i].Annotations = l[i].Annotations + } + return locations +} + +func toSyftDocument(sbomSBOM *sbom.SBOM) v1beta1.SyftDocument { + doc := syftjson.ToFormatModel(*sbomSBOM, syftjson.EncoderConfig{ + Pretty: false, + Legacy: false, + }) + configuration, _ := json.Marshal(doc.Descriptor.Configuration) + metadata, _ := json.Marshal(doc.Source.Metadata) + syftDocument := v1beta1.SyftDocument{ + Artifacts: toSyftPackages(doc.Artifacts), + ArtifactRelationships: toSyftRelationships(doc.ArtifactRelationships), + Files: make([]v1beta1.SyftFile, len(doc.Files)), + SyftSource: v1beta1.SyftSource{ + ID: doc.Source.ID, + Name: doc.Source.Name, + Version: doc.Source.Version, + Type: doc.Source.Type, + Metadata: metadata, + }, + Distro: v1beta1.LinuxRelease{ + PrettyName: doc.Distro.PrettyName, + Name: doc.Distro.Name, + ID: doc.Distro.ID, + IDLike: v1beta1.IDLikes(doc.Distro.IDLike), + Version: doc.Distro.Version, + VersionID: doc.Distro.VersionID, + VersionCodename: doc.Distro.VersionCodename, + BuildID: doc.Distro.BuildID, + ImageID: doc.Distro.ImageID, + ImageVersion: doc.Distro.ImageVersion, + Variant: doc.Distro.Variant, + VariantID: doc.Distro.VariantID, + HomeURL: doc.Distro.HomeURL, + SupportURL: doc.Distro.SupportURL, + BugReportURL: doc.Distro.BugReportURL, + PrivacyPolicyURL: doc.Distro.PrivacyPolicyURL, + CPEName: doc.Distro.CPEName, + SupportEnd: doc.Distro.SupportEnd, + }, + SyftDescriptor: v1beta1.SyftDescriptor{ + Name: doc.Descriptor.Name, + Version: doc.Descriptor.Version, + Configuration: configuration, + }, + Schema: v1beta1.Schema{ + Version: doc.Schema.Version, + URL: doc.Schema.URL, + }, + } + // convert files + for i := range doc.Files { + syftDocument.Files[i].ID = doc.Files[i].ID + syftDocument.Files[i].Location.RealPath = doc.Files[i].Location.RealPath + syftDocument.Files[i].Location.FileSystemID = doc.Files[i].Location.FileSystemID + syftDocument.Files[i].Metadata = toFileMetadataEntry(doc.Files[i].Metadata) + syftDocument.Files[i].Contents = doc.Files[i].Contents + syftDocument.Files[i].Digests = toDigests(doc.Files[i].Digests) + syftDocument.Files[i].Licenses = toFileLicenses(doc.Files[i].Licenses) + syftDocument.Files[i].Executable = toExecutable(doc.Files[i].Executable) + } + return syftDocument +} + +func toSyftPackages(p []model.Package) []v1beta1.SyftPackage { + packages := make([]v1beta1.SyftPackage, len(p)) + for i := range p { + packages[i].ID = p[i].ID + packages[i].Name = p[i].Name + packages[i].Version = p[i].Version + packages[i].Type = string(p[i].Type) + packages[i].FoundBy = p[i].FoundBy + packages[i].Locations = toLocations(p[i].Locations) + packages[i].Licenses = toLicenses(p[i].Licenses) + packages[i].Language = string(p[i].Language) + packages[i].CPEs = toCPEs(p[i].CPEs) + packages[i].PURL = p[i].PURL + packages[i].Metadata, _ = json.Marshal(p[i].Metadata) + packages[i].MetadataType = p[i].MetadataType + } + return packages +} + +func toSyftRelationships(r []model.Relationship) []v1beta1.SyftRelationship { + relationships := make([]v1beta1.SyftRelationship, len(r)) + for i := range r { + relationships[i].Parent = r[i].Parent + relationships[i].Child = r[i].Child + relationships[i].Type = r[i].Type + } + return relationships +} diff --git a/pkg/sbommanager/v1/sbom_manager_test.go b/pkg/sbommanager/v1/sbom_manager_test.go new file mode 100644 index 00000000..42649498 --- /dev/null +++ b/pkg/sbommanager/v1/sbom_manager_test.go @@ -0,0 +1,64 @@ +package v1 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNormalizeimageDigest(t *testing.T) { + tests := []struct { + name string + imageDigest string + imageName string + want string + }{ + { + name: "replicaset-kubevuln-666dbffc4f-kubevuln-ca1b-6f47", + imageDigest: "quay.io/kubescape/kubevuln@sha256:94cbbb94f8d6bdf2529d5f9c5279ac4c7411182f4e8e5a3d0b5e8f10a465f73a", + imageName: "quay.io/kubescape/kubevuln:v0.3.2", + want: "quay.io/kubescape/kubevuln@sha256:94cbbb94f8d6bdf2529d5f9c5279ac4c7411182f4e8e5a3d0b5e8f10a465f73a", + }, + { + name: "trap", + imageDigest: "sha256:94cbbb94f8d6bdf2529d5f9c5279ac4c7411182f4e8e5a3d0b5e8f10a465f73a", + imageName: "quay.io/kubescape/kubevuln@sha256:94cbbb94f8d6bdf2529d5f9c5279ac4c7411182f4e8e5a3d0b5e8f10a465f73a", + want: "quay.io/kubescape/kubevuln@sha256:94cbbb94f8d6bdf2529d5f9c5279ac4c7411182f4e8e5a3d0b5e8f10a465f73a", + }, + { + name: "trap 2", + imageDigest: "@sha256:94cbbb94f8d6bdf2529d5f9c5279ac4c7411182f4e8e5a3d0b5e8f10a465f73a", + imageName: "quay.io/kubescape/kubevuln@sha256:94cbbb94f8d6bdf2529d5f9c5279ac4c7411182f4e8e5a3d0b5e8f10a465f73a", + want: "quay.io/kubescape/kubevuln@sha256:94cbbb94f8d6bdf2529d5f9c5279ac4c7411182f4e8e5a3d0b5e8f10a465f73a", + }, + { + name: "trap 3", + imageDigest: "titi@toto@sha256:94cbbb94f8d6bdf2529d5f9c5279ac4c7411182f4e8e5a3d0b5e8f10a465f73a", + imageName: "quay.io/kubescape/kubevuln@sha256:94cbbb94f8d6bdf2529d5f9c5279ac4c7411182f4e8e5a3d0b5e8f10a465f73a", + want: "quay.io/kubescape/kubevuln@sha256:94cbbb94f8d6bdf2529d5f9c5279ac4c7411182f4e8e5a3d0b5e8f10a465f73a", + }, + { + name: "quay.io-kubescape-kubescape-v3.0.3-88a469", + imageDigest: "86413975e2d0330176894e4f3f5987505ed27b1191f2537797fbbf345b88a469", + imageName: "quay.io/kubescape/kubescape:v3.0.3", + want: "quay.io/kubescape/kubescape@sha256:86413975e2d0330176894e4f3f5987505ed27b1191f2537797fbbf345b88a469", + }, + { + name: "registry.k8s.io-kube-scheduler-v1.28.4-3d2c54", + imageDigest: "sha256:05c284c929889d88306fdb3dd14ee2d0132543740f9e247685243214fc3d2c54", + imageName: "registry.k8s.io/kube-scheduler:v1.28.4", + want: "registry.k8s.io/kube-scheduler@sha256:05c284c929889d88306fdb3dd14ee2d0132543740f9e247685243214fc3d2c54", + }, + { + name: "replicaset-nginx-bf5d5cf98", + imageDigest: "sha256:28402db69fec7c17e179ea87882667f1e054391138f77ffaf0c3eb388efc3ffb", + imageName: "docker.io/library/nginx:latest", + want: "docker.io/library/nginx@sha256:28402db69fec7c17e179ea87882667f1e054391138f77ffaf0c3eb388efc3ffb", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, normalizeImageID(tt.imageName, tt.imageDigest), "normalizeimageDigest(%v, %v)", tt.imageDigest, tt.imageName) + }) + } +} diff --git a/pkg/sbommanager/v1/source.go b/pkg/sbommanager/v1/source.go new file mode 100644 index 00000000..690aad6e --- /dev/null +++ b/pkg/sbommanager/v1/source.go @@ -0,0 +1,218 @@ +package v1 + +import ( + "encoding/json" + "errors" + "fmt" + "slices" + "strings" + "sync" + "time" + + "github.com/anchore/syft/syft/artifact" + "github.com/anchore/syft/syft/file" + "github.com/anchore/syft/syft/source" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/kubescape/node-agent/pkg/utils" + imagedigest "github.com/opencontainers/go-digest" + imagespec "github.com/opencontainers/image-spec/specs-go/v1" + runtime "k8s.io/cri-api/pkg/apis/runtime/v1" +) + +var ( + ErrImageTooLarge = errors.New("image size exceeds maximum allowed size") +) + +type NodeSource struct { + description source.Description + layers []imagedigest.Digest + mounts []string + resolver file.Resolver + mutex *sync.Mutex +} + +var _ source.Source = (*NodeSource)(nil) + +type ImageInfo struct { + ImageSpec imagespec.Image `json:"imageSpec"` +} + +func NewSource(imageName, imageDigest, imageID string, imageStatus *runtime.ImageStatusResponse, mounts []string, maxImageSize int64) (*NodeSource, error) { + // unmarshal image info + var imageInfo ImageInfo + err := json.Unmarshal([]byte(imageStatus.Info["info"]), &imageInfo) + if err != nil { + return nil, fmt.Errorf("unable to unmarshal image info: %w", err) + } + reverseLayers := imageInfo.ImageSpec.RootFS.DiffIDs + // reverse layers to match the order of the mounts + slices.Reverse(reverseLayers) + // prepare image config + configFile := v1.ConfigFile{ + Architecture: imageInfo.ImageSpec.Architecture, + Author: imageInfo.ImageSpec.Author, + Container: "", + Created: toTime(imageInfo.ImageSpec.Created), + DockerVersion: "", + History: toHistory(imageInfo.ImageSpec.History), + OS: imageInfo.ImageSpec.OS, + RootFS: toRootFS(imageInfo.ImageSpec.RootFS), + Config: toConfig(imageInfo.ImageSpec.Config), + OSVersion: imageInfo.ImageSpec.Platform.OSVersion, + Variant: imageInfo.ImageSpec.Platform.Variant, + OSFeatures: imageInfo.ImageSpec.Platform.OSFeatures, + } + rawConfig, err := json.Marshal(configFile) + if err != nil { + return nil, fmt.Errorf("unable to marshal image config: %w", err) + } + layers, totalSize := toLayers(imageInfo.ImageSpec.RootFS.DiffIDs, mounts) + // check total size + if totalSize > maxImageSize { + return nil, ErrImageTooLarge + } + return &NodeSource{ + description: source.Description{ + ID: strings.Replace(imageDigest, "sha256:", "", 1), + Name: imageName, + Version: imageDigest, + Metadata: source.ImageMetadata{ + UserInput: imageID, + ID: imageStatus.Image.Id, + ManifestDigest: "", + MediaType: "", + Tags: imageStatus.Image.RepoTags, + Size: totalSize, + Layers: layers, + RawManifest: nil, + RawConfig: rawConfig, + RepoDigests: imageStatus.Image.RepoDigests, + Architecture: imageInfo.ImageSpec.Architecture, + Variant: imageInfo.ImageSpec.Variant, + OS: imageInfo.ImageSpec.OS, + Labels: imageInfo.ImageSpec.Config.Labels, + }, + }, + layers: reverseLayers, + mounts: mounts, + mutex: &sync.Mutex{}, + }, nil +} + +func toConfig(config imagespec.ImageConfig) v1.Config { + return v1.Config{ + AttachStderr: false, + AttachStdin: false, + AttachStdout: false, + Cmd: config.Cmd, + Healthcheck: &v1.HealthConfig{ + Test: nil, + Interval: 0, + Timeout: 0, + StartPeriod: 0, + Retries: 0, + }, + Domainname: "", + Entrypoint: config.Entrypoint, + Env: config.Env, + Hostname: "", + Image: "", + Labels: config.Labels, + OnBuild: nil, + OpenStdin: false, + StdinOnce: false, + Tty: false, + User: "", + Volumes: config.Volumes, + WorkingDir: config.WorkingDir, + ExposedPorts: config.ExposedPorts, + ArgsEscaped: config.ArgsEscaped, + NetworkDisabled: false, + MacAddress: "", + StopSignal: config.StopSignal, + Shell: nil, + } +} + +func toDiffIDs(ds []imagedigest.Digest) []v1.Hash { + hashes := make([]v1.Hash, len(ds)) + for i, d := range ds { + hashes[i] = v1.Hash{ + Algorithm: string(d.Algorithm()), + Hex: d.Hex(), + } + } + return hashes +} + +func toHistory(history []imagespec.History) []v1.History { + histories := make([]v1.History, len(history)) + for i, h := range history { + histories[i] = v1.History{ + CreatedBy: h.CreatedBy, + Comment: h.Comment, + Created: toTime(h.Created), + EmptyLayer: h.EmptyLayer, + } + } + return histories +} + +func toLayers(ds []imagedigest.Digest, ms []string) ([]source.LayerMetadata, int64) { + var totalSize int64 + layers := make([]source.LayerMetadata, len(ds)) + msLen := len(ms) + for i, d := range ds { + s := utils.DiskUsage(ms[msLen-i-1]) + totalSize += s + layers[i] = source.LayerMetadata{ + MediaType: "application/vnd.oci.image.layer.v1.tar+gzip", + Digest: d.String(), + Size: s, + } + } + return layers, totalSize +} + +func toRootFS(rootFS imagespec.RootFS) v1.RootFS { + return v1.RootFS{ + Type: rootFS.Type, + DiffIDs: toDiffIDs(rootFS.DiffIDs), + } +} + +func toTime(created *time.Time) v1.Time { + if created == nil { + return v1.Time{} + } + return v1.Time{ + Time: *created, + } +} + +func (n *NodeSource) ID() artifact.ID { + return artifact.ID(n.description.ID) +} + +func (n *NodeSource) FileResolver(scope source.Scope) (file.Resolver, error) { + n.mutex.Lock() + defer n.mutex.Unlock() + + if n.resolver == nil { + var err error + n.resolver, err = NewResolver(scope, n.layers, n.mounts) + if err != nil { + return nil, fmt.Errorf("unable to create file resolver: %w", err) + } + } + + return n.resolver, nil +} + +func (n *NodeSource) Describe() source.Description { + return n.description +} + +func (n *NodeSource) Close() error { + return nil +} diff --git a/pkg/seccompmanager/v1/seccomp_manager.go b/pkg/seccompmanager/v1/seccomp_manager.go index b2e6aae3..0258448f 100644 --- a/pkg/seccompmanager/v1/seccomp_manager.go +++ b/pkg/seccompmanager/v1/seccomp_manager.go @@ -7,13 +7,12 @@ import ( "path/filepath" "slices" - "github.com/kubescape/node-agent/pkg/seccompmanager" - securejoin "github.com/cyphar/filepath-securejoin" mapset "github.com/deckarep/golang-set/v2" "github.com/goradd/maps" "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" + "github.com/kubescape/node-agent/pkg/seccompmanager" "github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1" v1beta1api "github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1" "github.com/spf13/afero" @@ -117,7 +116,7 @@ func getProfilesDir() (string, error) { kubeletRoot = "/var/lib/kubelet" } // use securejoin to join the two, add seccomp and store in seccompProfilesDir - seccompProfilesDir, err := securejoin.SecureJoin(filepath.Join(hostRoot, kubeletRoot), "seccomp") + seccompProfilesDir, err := securejoin.SecureJoin(hostRoot, filepath.Join(kubeletRoot, "seccomp")) if err != nil { return "", fmt.Errorf("failed to join seccomp profiles dir: %w", err) } diff --git a/pkg/storage/storage_interface.go b/pkg/storage/storage_interface.go index 49bc0972..84d970ba 100644 --- a/pkg/storage/storage_interface.go +++ b/pkg/storage/storage_interface.go @@ -12,7 +12,10 @@ type StorageClient interface { GetApplicationProfile(namespace, name string) (*v1beta1.ApplicationProfile, error) CreateFilteredSBOM(SBOM *v1beta1.SBOMSyftFiltered) error GetFilteredSBOM(name string) (*v1beta1.SBOMSyftFiltered, error) + CreateSBOM(SBOM *v1beta1.SBOMSyft) (*v1beta1.SBOMSyft, error) GetSBOM(name string) (*v1beta1.SBOMSyft, error) + GetSBOMMeta(name string) (*v1beta1.SBOMSyft, error) + ReplaceSBOM(SBOM *v1beta1.SBOMSyft) (*v1beta1.SBOMSyft, error) IncrementImageUse(imageID string) DecrementImageUse(imageID string) GetNetworkNeighbors(namespace, name string) (*v1beta1.NetworkNeighbors, error) diff --git a/pkg/storage/storage_mock.go b/pkg/storage/storage_mock.go index 6a0ee6d2..10934080 100644 --- a/pkg/storage/storage_mock.go +++ b/pkg/storage/storage_mock.go @@ -16,6 +16,7 @@ type StorageHttpClientMock struct { ApplicationActivities []*spdxv1beta1.ApplicationActivity ApplicationProfiles []*spdxv1beta1.ApplicationProfile FilteredSyftSBOMs []*spdxv1beta1.SBOMSyftFiltered + SyftSBOMs []*spdxv1beta1.SBOMSyft NetworkNeighborhoods []*v1beta1.NetworkNeighborhood NetworkNeighborses []*v1beta1.NetworkNeighbors ImageCounters map[string]int @@ -56,10 +57,24 @@ func (sc *StorageHttpClientMock) GetFilteredSBOM(name string) (*v1beta1.SBOMSyft return nil, errors.New("not found") } +func (sc *StorageHttpClientMock) CreateSBOM(SBOM *v1beta1.SBOMSyft) (*v1beta1.SBOMSyft, error) { + sc.SyftSBOMs = append(sc.SyftSBOMs, SBOM) + return SBOM, nil +} + func (sc *StorageHttpClientMock) GetSBOM(_ string) (*v1beta1.SBOMSyft, error) { return sc.mockSBOM, nil } +func (sc *StorageHttpClientMock) GetSBOMMeta(_ string) (*v1beta1.SBOMSyft, error) { + return sc.mockSBOM, nil +} + +func (sc *StorageHttpClientMock) ReplaceSBOM(SBOM *v1beta1.SBOMSyft) (*v1beta1.SBOMSyft, error) { + sc.SyftSBOMs = append(sc.SyftSBOMs, SBOM) + return SBOM, nil +} + func (sc *StorageHttpClientMock) PatchFilteredSBOM(_ string, _ *spdxv1beta1.SBOMSyftFiltered) error { return nil } diff --git a/pkg/storage/v1/storage.go b/pkg/storage/v1/storage.go index e51fc46e..8419e9f3 100644 --- a/pkg/storage/v1/storage.go +++ b/pkg/storage/v1/storage.go @@ -9,22 +9,21 @@ import ( "strings" "time" - "github.com/kubescape/node-agent/pkg/config" - "github.com/kubescape/node-agent/pkg/storage" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/client-go/util/retry" - "github.com/cenkalti/backoff/v4" "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" + "github.com/kubescape/node-agent/pkg/config" + "github.com/kubescape/node-agent/pkg/storage" "github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1" "github.com/kubescape/storage/pkg/generated/clientset/versioned" "github.com/kubescape/storage/pkg/generated/clientset/versioned/fake" spdxv1beta1 "github.com/kubescape/storage/pkg/generated/clientset/versioned/typed/softwarecomposition/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/util/retry" ) const ( @@ -183,10 +182,22 @@ func (sc Storage) GetFilteredSBOM(name string) (*v1beta1.SBOMSyftFiltered, error return sc.StorageClient.SBOMSyftFiltereds(sc.namespace).Get(context.Background(), name, metav1.GetOptions{}) } +func (sc Storage) CreateSBOM(SBOM *v1beta1.SBOMSyft) (*v1beta1.SBOMSyft, error) { + return sc.StorageClient.SBOMSyfts(sc.namespace).Create(context.Background(), SBOM, metav1.CreateOptions{}) +} + func (sc Storage) GetSBOM(name string) (*v1beta1.SBOMSyft, error) { return sc.StorageClient.SBOMSyfts(sc.namespace).Get(context.Background(), name, metav1.GetOptions{}) } +func (sc Storage) GetSBOMMeta(name string) (*v1beta1.SBOMSyft, error) { + return sc.StorageClient.SBOMSyfts(sc.namespace).Get(context.Background(), name, metav1.GetOptions{ResourceVersion: "metadata"}) +} + +func (sc Storage) ReplaceSBOM(SBOM *v1beta1.SBOMSyft) (*v1beta1.SBOMSyft, error) { + return sc.StorageClient.SBOMSyfts(sc.namespace).Update(context.Background(), SBOM, metav1.UpdateOptions{}) +} + func (sc Storage) PatchFilteredSBOM(name string, sbom *v1beta1.SBOMSyftFiltered) error { bytes, err := json.Marshal(sbom) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 7dded0a6..4a702e46 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -789,3 +789,28 @@ func decodeConfigz(respBody []byte) (*kubeletconfigv1beta1.KubeletConfiguration, return &configz.ComponentConfig, nil } + +func DiskUsage(path string) int64 { + var s int64 + dir, err := os.Open(path) + if err != nil { + fmt.Println(err) + return s + } + defer dir.Close() + + files, err := dir.Readdir(-1) + if err != nil { + fmt.Println(err) + return s + } + + for _, f := range files { + if f.IsDir() { + s += DiskUsage(filepath.Join(path, f.Name())) + } else { + s += f.Size() + } + } + return s +}