From e87fbf112e4ba5d631ec86e425cf559587ee062b Mon Sep 17 00:00:00 2001 From: Christian Kotzbauer Date: Thu, 16 Jun 2022 08:38:37 +0200 Subject: [PATCH] cleanup: moved registry package to libk8soci Signed-off-by: Christian Kotzbauer --- go.mod | 11 +- go.sum | 27 ++--- internal/job/job.go | 4 +- internal/kubernetes/kubernetes.go | 17 +-- internal/registry/configfile.go | 94 ---------------- internal/registry/configfile_test.go | 65 ----------- internal/registry/registry.go | 154 -------------------------- internal/registry/registry_test.go | 158 --------------------------- internal/syft/syft.go | 4 +- internal/syft/syft_test.go | 9 +- 10 files changed, 31 insertions(+), 512 deletions(-) delete mode 100644 internal/registry/configfile.go delete mode 100644 internal/registry/configfile_test.go delete mode 100644 internal/registry/registry.go delete mode 100644 internal/registry/registry_test.go diff --git a/go.mod b/go.mod index bf30901c..d1da180c 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,9 @@ go 1.18 require ( github.com/anchore/syft v0.47.0 - github.com/docker/cli v20.10.17+incompatible + github.com/ckotzbauer/libk8soci v0.0.0-20220616062755-33820a752d05 github.com/novln/docker-parser v1.0.0 github.com/nscuro/dtrack-client v0.5.0 - github.com/pkg/errors v0.9.1 github.com/robfig/cron v1.2.0 github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.4.0 @@ -27,15 +26,15 @@ require ( github.com/acobaugh/osrelease v0.1.0 // indirect github.com/acomagu/bufpipe v1.0.3 // indirect github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb // indirect - github.com/anchore/go-rpmdb v0.0.0-20210914181456-a9c52348da63 // indirect github.com/anchore/packageurl-go v0.1.1-0.20220428202044-a072fa3cb6d7 // indirect github.com/anchore/stereoscope v0.0.0-20220518185348-c97a3c6ffc67 // indirect github.com/andybalholm/brotli v1.0.4 // indirect github.com/bmatcuk/doublestar/v4 v4.0.2 // indirect github.com/containerd/containerd v1.6.6 // indirect github.com/containerd/stargz-snapshotter/estargz v0.11.4 // indirect + github.com/docker/cli v20.10.17+incompatible // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v20.10.16+incompatible // indirect + github.com/docker/docker v20.10.17+incompatible // indirect github.com/docker/docker-credential-helpers v0.6.4 // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect @@ -85,10 +84,10 @@ require ( github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect github.com/pierrec/lz4/v4 v4.1.2 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/rivo/uniseg v0.2.0 // indirect - github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e // indirect github.com/sergi/go-diff v1.2.0 // indirect github.com/spdx/tools-golang v0.2.0 // indirect @@ -141,7 +140,7 @@ require ( github.com/spf13/pflag v1.0.5 golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 // indirect golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect + golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect diff --git a/go.sum b/go.sum index 43d1e8f1..56b937ba 100644 --- a/go.sum +++ b/go.sum @@ -130,16 +130,12 @@ github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:C github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= 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-rpmdb v0.0.0-20210914181456-a9c52348da63 h1:C9W/LAydEz/qdUhx1MdjO9l8NEcFKYknkxDVyo9LAoM= -github.com/anchore/go-rpmdb v0.0.0-20210914181456-a9c52348da63/go.mod h1:6qH8c6U/3CBVvDDDBZnPSTbTINq3cIdADUYTaVf75EM= 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/packageurl-go v0.1.1-0.20220428202044-a072fa3cb6d7 h1:kDrYkTSM9uIxaX/P9s0F4nKYNM+hnSgLJdLpqvsaQ/g= github.com/anchore/packageurl-go v0.1.1-0.20220428202044-a072fa3cb6d7/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4= github.com/anchore/stereoscope v0.0.0-20220518185348-c97a3c6ffc67 h1:nbcYgEEv9CLnuKg/8ExvXDiEpCA9pwZcyyraZyBE+aw= github.com/anchore/stereoscope v0.0.0-20220518185348-c97a3c6ffc67/go.mod h1:yoCLUZY0k/pYLNIy0L80p2Ko0PKVNXm8rHtgxp4OiSc= -github.com/anchore/syft v0.46.3 h1:TKD14BrLiLrWamQI2r46v1Rhl2khNlQXzomhTmkqQ4Y= -github.com/anchore/syft v0.46.3/go.mod h1:7H/MkAj2uV4cD08e1MB04m3IJp8oGRJ9Y9CDfGRc94U= github.com/anchore/syft v0.47.0 h1:ER/c3hIqE/f23REZcoz88NJYyrpWjgmKojPwtlRBlVU= github.com/anchore/syft v0.47.0/go.mod h1:7R9U/NZu+VCBFNolgp+g4UfSkxq4U0c1ruq8/7GHZTY= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= @@ -208,6 +204,8 @@ github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLI github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/ckotzbauer/libk8soci v0.0.0-20220616062755-33820a752d05 h1:tkzw6L5Yxd8Tl6FMgeTKo/Rl9LrjvnKQzF9tCiCbzPo= +github.com/ckotzbauer/libk8soci v0.0.0-20220616062755-33820a752d05/go.mod h1:bCO4JZ7vub7ma+5Civ6GJrIH4Qi3HOcY7h+7L4KRuec= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 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= @@ -352,8 +350,6 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v20.10.10+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v20.10.12+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v20.10.16+incompatible h1:aLQ8XowgKpR3/IysPj8qZQJBVQ+Qws61icFuZl6iKYs= -github.com/docker/cli v20.10.16+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M= github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= @@ -364,8 +360,8 @@ github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6 github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v20.10.10+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.16+incompatible h1:2Db6ZR/+FUR3hqPMwnogOPHFn405crbpxvWzKovETOQ= -github.com/docker/docker v20.10.16+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.17+incompatible h1:JYCuMrWaVNophQTOrMMoSwudOVEfcegoZZrleKc1xwE= +github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o= github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= @@ -483,7 +479,6 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-sql-driver/mysql v1.5.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 v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= @@ -838,6 +833,7 @@ github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4 github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.10 h1:MLn+5bFRlWMGoSRmJour3CL1w/qL96mvipqpwQW/Sfk= github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -993,7 +989,6 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pierrec/lz4/v4 v4.1.2 h1:qvY3YFXRQE/XB8MlLzJH7mSzBs74eA2gg52YTk6jUPM= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1058,7 +1053,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= @@ -1152,7 +1146,6 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= @@ -1547,8 +1540,8 @@ golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= @@ -1570,8 +1563,6 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs= -golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w= golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2007,7 +1998,9 @@ modernc.org/ccgo/v3 v3.13.1/go.mod h1:aBYVOUfIlcSnrsRVU8VRS35y2DIfpgkmVkYZ0tpIXi modernc.org/ccgo/v3 v3.14.0/go.mod h1:hBrkiBlUwvr5vV/ZH9YzXIp982jKE8Ek8tR1ytoAL6Q= modernc.org/ccgo/v3 v3.15.1 h1:bagyhO7uFlYWedkh6mfIYf8LZGYnVGPYh2FqXisaOV4= modernc.org/ccgo/v3 v3.15.1/go.mod h1:md59wBwDT2LznX/OTCPoVS6KIsdRgY8xqQwBV+hkTH0= +modernc.org/ccorpus v1.11.1 h1:K0qPfpVG1MJh5BYazccnmhywH4zHuOgJXgbjzyp6dWA= modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q= @@ -2065,10 +2058,12 @@ modernc.org/sqlite v1.14.5 h1:bYrrjwH9Y7QUGk1MbchZDhRfmpGuEAs/D45sVjNbfvs= modernc.org/sqlite v1.14.5/go.mod h1:YyX5Rx0WbXokitdWl2GJIDy4BrPxBP0PwwhpXOHCDLE= modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/tcl v1.10.0 h1:vux2MNFhSXYqD8Kq4Uc9RjWcgv2c7Atx3da3VpLPPEw= modernc.org/tcl v1.10.0/go.mod h1:WzWapmP/7dHVhFoyPpEaNSVTL8xtewhouN/cqSJ5A2s= modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.2.21/go.mod h1:uXrObx4pGqXWIMliC5MiKuwAyMrltzwpteOFUP1PWCc= +modernc.org/z v1.3.0 h1:4RWULo1Nvaq5ZBhbLe74u8p6tV4Mmm0ZrPBXYPm/xjM= modernc.org/z v1.3.0/go.mod h1:+mvgLH814oDjtATDdT3rs84JnUIpkvAF5B8AVkNlE2g= mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= diff --git a/internal/job/job.go b/internal/job/job.go index 95c67cbe..ad743896 100644 --- a/internal/job/job.go +++ b/internal/job/job.go @@ -11,8 +11,8 @@ import ( corev1 "k8s.io/api/core/v1" meta "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/ckotzbauer/libk8soci/pkg/oci" "github.com/ckotzbauer/sbom-operator/internal/kubernetes" - "github.com/ckotzbauer/sbom-operator/internal/registry" "github.com/sirupsen/logrus" ) @@ -53,7 +53,7 @@ func (j JobClient) StartJob(images map[string]kubernetes.ContainerImage) (*batch podNamespace := os.Getenv("POD_NAMESPACE") for _, image := range images { - cfg, err := registry.ResolveAuthConfig(image) + cfg, err := oci.ResolveAuthConfig(oci.RegistryImage{ImageID: image.ImageID, PullSecrets: image.PullSecrets}) if err != nil { logrus.WithError(err).Error("Error occurred during auth-resolve") return nil, err diff --git a/internal/kubernetes/kubernetes.go b/internal/kubernetes/kubernetes.go index c2d1599d..397e80b7 100644 --- a/internal/kubernetes/kubernetes.go +++ b/internal/kubernetes/kubernetes.go @@ -16,20 +16,15 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" + "github.com/ckotzbauer/libk8soci/pkg/oci" "github.com/ckotzbauer/sbom-operator/internal" ) -type KubeCreds struct { - SecretName string - SecretCredsData []byte - IsLegacySecret bool -} - type ContainerImage struct { Image string ImageID string Pods []corev1.Pod - PullSecrets []KubeCreds + PullSecrets []oci.KubeCreds } type KubeClient struct { @@ -105,7 +100,7 @@ func (client *KubeClient) LoadImageInfos(namespaces []corev1.Namespace, podLabel } for _, pod := range pods { - allImageCreds := []KubeCreds{} + allImageCreds := []oci.KubeCreds{} annotations := pod.Annotations statuses := []corev1.ContainerStatus{} @@ -209,8 +204,8 @@ func (client *KubeClient) hasAnnotation(annotations map[string]string, status co return false } -func (client *KubeClient) loadSecrets(namespace string, secrets []corev1.LocalObjectReference) []KubeCreds { - allImageCreds := []KubeCreds{} +func (client *KubeClient) loadSecrets(namespace string, secrets []corev1.LocalObjectReference) []oci.KubeCreds { + allImageCreds := []oci.KubeCreds{} for _, s := range secrets { secret, err := client.Client.CoreV1().Secrets(namespace).Get(context.Background(), s.Name, meta.GetOptions{}) @@ -233,7 +228,7 @@ func (client *KubeClient) loadSecrets(namespace string, secrets []corev1.LocalOb } if len(creds) > 0 { - allImageCreds = append(allImageCreds, KubeCreds{SecretName: name, SecretCredsData: creds, IsLegacySecret: legacy}) + allImageCreds = append(allImageCreds, oci.KubeCreds{SecretName: name, SecretCredsData: creds, IsLegacySecret: legacy}) } } diff --git a/internal/registry/configfile.go b/internal/registry/configfile.go deleted file mode 100644 index 268faa57..00000000 --- a/internal/registry/configfile.go +++ /dev/null @@ -1,94 +0,0 @@ -package registry - -import ( - "encoding/base64" - "encoding/json" - "io" - "io/ioutil" - "strings" - - "github.com/docker/cli/cli/config/configfile" - "github.com/docker/cli/cli/config/types" - "github.com/pkg/errors" -) - -// This is ported from https://github.com/docker/cli/blob/v20.10.15/cli/config/configfile/file.go -// The only changes to the original source are the fact, that the "auth" field is not decoded -// when "username" or "password" are not blank to avoid overwrites. - -const ( - // This constant is only used for really old config files when the - // URL wasn't saved as part of the config file and it was just - // assumed to be this value. - defaultIndexServer = "https://index.docker.io/v1/" -) - -// LegacyLoadFromReader reads the non-nested configuration data given and sets up the -// auth config information with given directory and populates the receiver object -func LegacyLoadFromReader(configData io.Reader, configFile *configfile.ConfigFile) error { - b, err := ioutil.ReadAll(configData) - if err != nil { - return err - } - - if err := json.Unmarshal(b, &configFile.AuthConfigs); err != nil { - arr := strings.Split(string(b), "\n") - if len(arr) < 2 { - return errors.Errorf("The Auth config file is empty") - } - authConfig := types.AuthConfig{} - origAuth := strings.Split(arr[0], " = ") - if len(origAuth) != 2 { - return errors.Errorf("Invalid Auth config file") - } - - // Only decode the "auth" field when "username" and "password" are blank. - if len(authConfig.Username) == 0 && len(authConfig.Password) == 0 { - authConfig.Username, authConfig.Password, err = decodeAuth(origAuth[1]) - if err != nil { - return err - } - } - - authConfig.ServerAddress = defaultIndexServer - configFile.AuthConfigs[defaultIndexServer] = authConfig - } else { - for k, authConfig := range configFile.AuthConfigs { - // Only decode the "auth" field when "username" and "password" are blank. - if len(authConfig.Username) == 0 && len(authConfig.Password) == 0 { - authConfig.Username, authConfig.Password, err = decodeAuth(authConfig.Auth) - if err != nil { - return err - } - } - authConfig.Auth = "" - authConfig.ServerAddress = k - configFile.AuthConfigs[k] = authConfig - } - } - return nil -} - -// decodeAuth decodes a base64 encoded string and returns username and password -func decodeAuth(authStr string) (string, string, error) { - if authStr == "" { - return "", "", nil - } - - decLen := base64.StdEncoding.DecodedLen(len(authStr)) - decoded := make([]byte, decLen) - authByte := []byte(authStr) - n, err := base64.StdEncoding.Decode(decoded, authByte) - if err != nil { - return "", "", err - } - if n > decLen { - return "", "", errors.Errorf("Something went wrong decoding auth config") - } - arr := strings.SplitN(string(decoded), ":", 2) - if len(arr) != 2 { - return "", "", errors.Errorf("Invalid auth configuration file") - } - password := strings.Trim(arr[1], "\x00") - return arr[0], password, nil -} diff --git a/internal/registry/configfile_test.go b/internal/registry/configfile_test.go deleted file mode 100644 index 8c17302b..00000000 --- a/internal/registry/configfile_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package registry - -import ( - "io/ioutil" - "os" - "path/filepath" - "strings" - "testing" - - "github.com/docker/cli/cli/config" - "github.com/docker/cli/cli/config/configfile" - "github.com/docker/cli/cli/config/types" - "github.com/stretchr/testify/assert" -) - -func TestOldJSONReaderNoFile(t *testing.T) { - js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}` - configFile := configfile.ConfigFile{ - AuthConfigs: make(map[string]types.AuthConfig), - } - - err := LegacyLoadFromReader(strings.NewReader(js), &configFile) - assert.Nil(t, err) - - ac := configFile.AuthConfigs["https://index.docker.io/v1/"] - assert.Equal(t, ac.Username, "joejoe") - assert.Equal(t, ac.Password, "hello") -} - -func TestLegacyJSONSaveWithNoFile(t *testing.T) { - js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}` - configFile := configfile.ConfigFile{ - AuthConfigs: make(map[string]types.AuthConfig), - } - - err := LegacyLoadFromReader(strings.NewReader(js), &configFile) - assert.Nil(t, err) - err = configFile.Save() - assert.ErrorContains(t, err, "with empty filename") - - tmpHome, err := ioutil.TempDir("", "config-test") - assert.Nil(t, err) - defer os.RemoveAll(tmpHome) - - fn := filepath.Join(tmpHome, config.ConfigFileName) - f, _ := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) - defer f.Close() - - assert.Nil(t, configFile.SaveToWriter(f)) - buf, err := ioutil.ReadFile(filepath.Join(tmpHome, config.ConfigFileName)) - assert.Nil(t, err) - - expConfStr := `{ - "auths": { - "https://index.docker.io/v1/": { - "auth": "am9lam9lOmhlbGxv", - "email": "user@example.com" - } - } -}` - - if string(buf) != expConfStr { - t.Fatalf("Should have save in new form: \n%s\n not \n%s", string(buf), expConfStr) - } -} diff --git a/internal/registry/registry.go b/internal/registry/registry.go deleted file mode 100644 index 60bff636..00000000 --- a/internal/registry/registry.go +++ /dev/null @@ -1,154 +0,0 @@ -package registry - -import ( - "bytes" - "fmt" - - "github.com/docker/cli/cli/config" - "github.com/docker/cli/cli/config/configfile" - "github.com/docker/cli/cli/config/types" - "github.com/google/go-containerregistry/pkg/authn" - "github.com/google/go-containerregistry/pkg/crane" - "github.com/google/go-containerregistry/pkg/name" - v1 "github.com/google/go-containerregistry/pkg/v1" - "github.com/google/go-containerregistry/pkg/v1/remote" - "github.com/sirupsen/logrus" - - "github.com/ckotzbauer/sbom-operator/internal/kubernetes" - - parser "github.com/novln/docker-parser" -) - -var ( - ErrorNoValidPullSecret = fmt.Errorf("No valid or valid-but-unauthorized PullSecret found from ContainerImage") -) - -func SaveImage(imagePath string, image kubernetes.ContainerImage) error { - o := crane.GetOptions() - var err error - var cfg types.AuthConfig - empty := types.AuthConfig{} - - if len(image.PullSecrets) == 0 { - _, err := downloadImage(imagePath, image, o) - if err != nil { - logrus.WithError(err).Error() - } - - return err - } else { - for _, pullSecret := range image.PullSecrets { - cfg, err = resolveAuthConfigWithPullSecret(image, pullSecret) - if err != nil { - logrus.WithError(err).Warnf("image: %s, Read authentication configuration from secret: %s failed", image.ImageID, pullSecret.SecretName) - continue - } - - if cfg != empty { - o.Remote = []remote.Option{ - remote.WithAuth(authn.FromConfig(authn.AuthConfig{ - Username: cfg.Username, - Password: cfg.Password, - Auth: cfg.Auth, - IdentityToken: cfg.IdentityToken, - RegistryToken: cfg.RegistryToken, - })), - } - } - - proceed, err := downloadImage(imagePath, image, o) - if !proceed && err == nil { - logrus.Debugf("Image %s successfully pulled with PullSecret: %s", image.ImageID, pullSecret.SecretName) - return nil - } else if !proceed && err != nil { - logrus.WithError(err).Error() - return err - } else if proceed && err != nil { - logrus.WithError(err).Debug() - } - } - } - - // no valid pull request found for this image - returning an error - return ErrorNoValidPullSecret -} - -func downloadImage(imagePath string, image kubernetes.ContainerImage, o crane.Options) (bool, error) { - imageMap := map[string]v1.Image{} - ref, err := name.ParseReference(image.ImageID, o.Name...) - - if err != nil { - // should stop immediately because it seems that no other pullSecret will solve this problem - return false, fmt.Errorf("parsing reference %q: %w", image.ImageID, err) - } - - rmt, err := remote.Get(ref, o.Remote...) - if err != nil { - // should continue, because, this might be an Authentication Error - return true, fmt.Errorf("image: %s, Image-Pull Error: %w", image.ImageID, err) - } - - img, err := rmt.Image() - if err != nil { - // should stop immediately because no other pullSecret will solve this problem - return false, err - } - - imageMap[image.ImageID] = img - - if err := crane.MultiSave(imageMap, imagePath); err != nil { - // should stop immediately because no other pullSecret will solve this problem - return false, fmt.Errorf("saving tarball %s: %w", imagePath, err) - } - - // pull was sucessfull - no error occurred - return false, nil -} - -func resolveAuthConfigWithPullSecret(image kubernetes.ContainerImage, pullSecret kubernetes.KubeCreds) (types.AuthConfig, error) { - var cf *configfile.ConfigFile - var err error - - if pullSecret.IsLegacySecret { - cf = configfile.New("") - err = LegacyLoadFromReader(bytes.NewReader(pullSecret.SecretCredsData), cf) - } else { - cf, err = config.LoadFromReader(bytes.NewReader(pullSecret.SecretCredsData)) - } - - if err != nil { - return types.AuthConfig{}, err - } - - fullRef, err := parser.Parse(image.ImageID) - if err != nil { - return types.AuthConfig{}, err - } - - reg, err := name.NewRegistry(fullRef.Registry()) - if err != nil { - return types.AuthConfig{}, err - } - - regKey := reg.RegistryStr() - - if regKey == name.DefaultRegistry { - regKey = authn.DefaultAuthKey - } - - cfg, err := cf.GetAuthConfig(regKey) - if err != nil { - return types.AuthConfig{}, err - } - - return cfg, nil -} - -func ResolveAuthConfig(image kubernetes.ContainerImage) (types.AuthConfig, error) { - // to not break JobImages this function needs to redirect to the actual resolve-function, using the first pullSecret from the list if exists - if len(image.PullSecrets) > 0 { - return resolveAuthConfigWithPullSecret(image, image.PullSecrets[0]) - } else { - return types.AuthConfig{}, nil - } -} diff --git a/internal/registry/registry_test.go b/internal/registry/registry_test.go deleted file mode 100644 index d6d132c5..00000000 --- a/internal/registry/registry_test.go +++ /dev/null @@ -1,158 +0,0 @@ -package registry_test - -import ( - "encoding/base64" - "os" - "testing" - - "github.com/ckotzbauer/sbom-operator/internal/kubernetes" - "github.com/ckotzbauer/sbom-operator/internal/registry" - "github.com/stretchr/testify/assert" -) - -type testData struct { - registry string - image string - legacy bool - imageSize int64 -} - -func TestRegistry(t *testing.T) { - tests := []testData{ - { - registry: "gcr", - image: "gcr.io/sbom-git-operator/integration-test-image:1.0.0", - legacy: false, - imageSize: 2823168, - }, - { - registry: "gar", - image: "europe-west3-docker.pkg.dev/sbom-git-operator/sbom-git-operator/integration-test-image:1.0.0", - legacy: false, - imageSize: 2823168, - }, - { - registry: "ecr", - image: "055403865123.dkr.ecr.eu-central-1.amazonaws.com/sbom-git-operator/integration-test-image:1.0.0", - legacy: false, - imageSize: 2823168, - }, - /*{ - registry: "acr", - image: "sbomgitoperator.azurecr.io/integration-test-image:1.0.0", - legacy: false, - imageSize: 2823168, - },*/ - { - registry: "hub", - image: "docker.io/ckotzbauer/integration-test-image:1.0.0", - legacy: false, - imageSize: 2823168, - }, - { - registry: "ghcr", - image: "ghcr.io/ckotzbauer-kubernetes-bot/sbom-git-operator-integration-test:1.0.0", - legacy: false, - imageSize: 2823168, - }, - { - registry: "legacy-ghcr", - image: "ghcr.io/ckotzbauer-kubernetes-bot/sbom-git-operator-integration-test:1.0.0", - legacy: true, - imageSize: 2823168, - }, - } - - unauthenticatedPositiveTest := testData{ - registry: "docker-io", - image: "hello-world:latest", - legacy: false, - imageSize: 7168, - } - - unauthenticatedNegativeTest := testData{ - registry: "ghcr", - image: "ghcr.io/ckotzbauer-kubernetes-bot/sbom-git-operator-integration-test:1.0.0", - legacy: false, - imageSize: 2823168, - } - - for _, v := range tests { - t.Run(v.registry, func(t *testing.T) { - testRegistry(t, v.registry, v.image, v.legacy, v.imageSize) - }) - } - - t.Run("unauthenticated positive", func(t *testing.T) { - testRegistryWithoutPullSecretsPositive(t, unauthenticatedPositiveTest.image, unauthenticatedPositiveTest.imageSize) - }) - - t.Run("unauthenticated negative", func(t *testing.T) { - testRegistryWithoutPullSecretsNegative(t, unauthenticatedNegativeTest.image) - }) - - t.Run("wrong secret negative", func(t *testing.T) { - testRegistryWithWrongPullSecretNegative(t, unauthenticatedNegativeTest.image) - }) -} - -func testRegistry(t *testing.T, name, image string, legacy bool, imageSize int64) { - b, err := os.ReadFile("../../auth/" + name + ".yaml") - assert.NoError(t, err) - - decoded, err := base64.StdEncoding.DecodeString(string(b)) - assert.NoError(t, err) - - file := "/tmp/1.0.0.tar.gz" - err = registry.SaveImage(file, kubernetes.ContainerImage{ - ImageID: image, - PullSecrets: []kubernetes.KubeCreds{{SecretName: name, SecretCredsData: []byte(decoded), IsLegacySecret: legacy}}, - }) - - if err == nil { - stat, _ := os.Stat(file) - assert.Equal(t, imageSize, stat.Size()) - } - - os.Remove(file) - assert.NoError(t, err) -} - -// this test should check if an image is pullable without pullSecrets (e.g. dockerhub - where it is really possible) -func testRegistryWithoutPullSecretsPositive(t *testing.T, image string, imageSize int64) { - file := "/tmp/1.0.0.tar.gz" - err := registry.SaveImage(file, kubernetes.ContainerImage{ImageID: image, PullSecrets: []kubernetes.KubeCreds{}}) - - if err == nil { - stat, _ := os.Stat(file) - assert.Equal(t, imageSize, stat.Size()) - } - - os.Remove(file) - assert.NoError(t, err) -} - -// this test should check if an image is not pullable without pullSecrets (e.g. internal registry - where it is forbidden) -// an error must be returned -func testRegistryWithoutPullSecretsNegative(t *testing.T, image string) { - file := "/tmp/1.0.0.tar.gz" - err := registry.SaveImage(file, kubernetes.ContainerImage{ImageID: image, PullSecrets: []kubernetes.KubeCreds{}}) - assert.Error(t, err) - os.Remove(file) -} - -// this test should check if an image is not pullable with wrong pullSecrets -// an error must be returned -func testRegistryWithWrongPullSecretNegative(t *testing.T, image string) { - file := "/tmp/1.0.0.tar.gz" - err := registry.SaveImage(file, kubernetes.ContainerImage{ - ImageID: image, - PullSecrets: []kubernetes.KubeCreds{{SecretName: "test", SecretCredsData: []byte{}, IsLegacySecret: false}}, - }) - - if assert.Error(t, err) { - assert.Equal(t, registry.ErrorNoValidPullSecret, err) - } - - os.Remove(file) -} diff --git a/internal/syft/syft.go b/internal/syft/syft.go index 0936b0ca..75387eb2 100644 --- a/internal/syft/syft.go +++ b/internal/syft/syft.go @@ -12,8 +12,8 @@ import ( "github.com/anchore/syft/syft/sbom" "github.com/anchore/syft/syft/source" + "github.com/ckotzbauer/libk8soci/pkg/oci" "github.com/ckotzbauer/sbom-operator/internal/kubernetes" - "github.com/ckotzbauer/sbom-operator/internal/registry" "github.com/sirupsen/logrus" parser "github.com/novln/docker-parser" @@ -46,7 +46,7 @@ func (s *Syft) ExecuteSyft(img kubernetes.ContainerImage) (string, error) { } imagePath := "/tmp/" + strings.ReplaceAll(fullRef.Tag(), ":", "_") + ".tar.gz" - err = registry.SaveImage(imagePath, img) + err = oci.SaveImage(imagePath, oci.RegistryImage{ImageID: img.ImageID, PullSecrets: img.PullSecrets}) if err != nil { logrus.WithError(err).Error("Image-Pull failed") diff --git a/internal/syft/syft_test.go b/internal/syft/syft_test.go index d583485e..2370cbd1 100644 --- a/internal/syft/syft_test.go +++ b/internal/syft/syft_test.go @@ -7,6 +7,7 @@ import ( "os" "testing" + "github.com/ckotzbauer/libk8soci/pkg/oci" "github.com/ckotzbauer/sbom-operator/internal/kubernetes" "github.com/ckotzbauer/sbom-operator/internal/syft" "github.com/stretchr/testify/assert" @@ -60,7 +61,7 @@ func marshalCyclonedx(t *testing.T, x interface{}) string { func testJsonSbom(t *testing.T, name, imageID string) { format := "json" s := syft.New(format).WithVersion("v9.9.9") - sbom, err := s.ExecuteSyft(kubernetes.ContainerImage{ImageID: imageID, PullSecrets: []kubernetes.KubeCreds{}}) + sbom, err := s.ExecuteSyft(kubernetes.ContainerImage{ImageID: imageID, PullSecrets: []oci.KubeCreds{}}) assert.NoError(t, err) @@ -84,7 +85,7 @@ func testJsonSbom(t *testing.T, name, imageID string) { func testCyclonedxSbom(t *testing.T, name, imageID string) { format := "cyclonedx" s := syft.New(format).WithVersion("v9.9.9") - sbom, err := s.ExecuteSyft(kubernetes.ContainerImage{ImageID: imageID, PullSecrets: []kubernetes.KubeCreds{}}) + sbom, err := s.ExecuteSyft(kubernetes.ContainerImage{ImageID: imageID, PullSecrets: []oci.KubeCreds{}}) assert.NoError(t, err) var output syftCyclonedxOutput @@ -104,7 +105,7 @@ func testCyclonedxSbom(t *testing.T, name, imageID string) { func testSpdxSbom(t *testing.T, name, imageID string) { format := "spdxjson" s := syft.New(format).WithVersion("v9.9.9") - sbom, err := s.ExecuteSyft(kubernetes.ContainerImage{ImageID: imageID, PullSecrets: []kubernetes.KubeCreds{}}) + sbom, err := s.ExecuteSyft(kubernetes.ContainerImage{ImageID: imageID, PullSecrets: []oci.KubeCreds{}}) assert.NoError(t, err) var output syftSpdxOutput @@ -128,7 +129,7 @@ func testSpdxSbom(t *testing.T, name, imageID string) { func testCyclonedxSbomWithoutPullSecrets(t *testing.T, name, imageID string) { format := "cyclonedx" s := syft.New(format).WithVersion("v9.9.9") - sbom, err := s.ExecuteSyft(kubernetes.ContainerImage{ImageID: imageID, PullSecrets: []kubernetes.KubeCreds{}}) + sbom, err := s.ExecuteSyft(kubernetes.ContainerImage{ImageID: imageID, PullSecrets: []oci.KubeCreds{}}) assert.NoError(t, err) var output syftCyclonedxOutput