diff --git a/internal/kubernetes/image.go b/internal/kubernetes/image.go new file mode 100644 index 00000000..1ab5fc46 --- /dev/null +++ b/internal/kubernetes/image.go @@ -0,0 +1,42 @@ +package kubernetes + +import ( + "fmt" + "strings" + + "github.com/ckotzbauer/libk8soci/pkg/oci" + parser "github.com/novln/docker-parser" + "github.com/novln/docker-parser/docker" + "github.com/sirupsen/logrus" +) + +func ApplyProxyRegistry(img *oci.RegistryImage, log bool, registryProxyMap map[string]string) error { + imageRef, err := parser.Parse(img.ImageID) + if err != nil { + logrus.WithError(err).Errorf("Could not parse image %s", img.ImageID) + return err + } + + for registryToReplace, proxyRegistry := range registryProxyMap { + if imageRef.Registry() == registryToReplace { + shortName := strings.TrimPrefix(imageRef.ShortName(), docker.DefaultRepoPrefix) + fullName := fmt.Sprintf("%s/%s", imageRef.Registry(), shortName) + if strings.HasPrefix(imageRef.Tag(), "sha256") { + fullName = fmt.Sprintf("%s@%s", fullName, imageRef.Tag()) + } else { + fullName = fmt.Sprintf("%s:%s", fullName, imageRef.Tag()) + } + + img.ImageID = strings.ReplaceAll(fullName, registryToReplace, proxyRegistry) + img.Image = strings.ReplaceAll(img.Image, registryToReplace, proxyRegistry) + + if log { + logrus.Debugf("Applied Registry-Proxy %s", img.ImageID) + } + + break + } + } + + return nil +} diff --git a/internal/kubernetes/image_test.go b/internal/kubernetes/image_test.go new file mode 100644 index 00000000..82eee8aa --- /dev/null +++ b/internal/kubernetes/image_test.go @@ -0,0 +1,59 @@ +package kubernetes_test + +import ( + "testing" + + "github.com/ckotzbauer/libk8soci/pkg/oci" + "github.com/ckotzbauer/sbom-operator/internal/kubernetes" + "github.com/stretchr/testify/assert" +) + +type mapTestData struct { + input string + expected string + dataMap map[string]string +} + +func TestApplyProxyRegistry(t *testing.T) { + tests := []mapTestData{ + { + input: "alpine:3.17", + expected: "alpine:3.17", + dataMap: make(map[string]string), + }, + { + input: "docker.io/alpine:3.17", + expected: "ghcr.io/alpine:3.17", + dataMap: map[string]string{"docker.io": "ghcr.io"}, + }, + { + input: "alpine:3.17", + expected: "ghcr.io/alpine:3.17", + dataMap: map[string]string{"docker.io": "ghcr.io"}, + }, + { + input: "alpine:3.17", + expected: "alpine:3.17", + dataMap: map[string]string{"ghcr.io": "docker.io"}, + }, + { + input: "alpine:3.17", + expected: "my.registry.com:5000/alpine:3.17", + dataMap: map[string]string{"docker.io": "my.registry.com:5000"}, + }, + { + input: "my.registry.com:5000/alpine:3.17", + expected: "ghcr.io/alpine:3.17", + dataMap: map[string]string{"my.registry.com:5000": "ghcr.io"}, + }, + } + + for _, v := range tests { + t.Run(v.input, func(t *testing.T) { + img := &oci.RegistryImage{ImageID: v.input, Image: v.input} + err := kubernetes.ApplyProxyRegistry(img, false, v.dataMap) + assert.NoError(t, err) + assert.Equal(t, v.expected, img.ImageID) + }) + } +} diff --git a/internal/processor/processor.go b/internal/processor/processor.go index 97d01ebe..f6df472f 100644 --- a/internal/processor/processor.go +++ b/internal/processor/processor.go @@ -7,6 +7,7 @@ import ( libk8s "github.com/ckotzbauer/libk8soci/pkg/kubernetes" liboci "github.com/ckotzbauer/libk8soci/pkg/oci" + "github.com/ckotzbauer/libstandard" "github.com/ckotzbauer/sbom-operator/internal" "github.com/ckotzbauer/sbom-operator/internal/job" "github.com/ckotzbauer/sbom-operator/internal/kubernetes" @@ -179,6 +180,11 @@ func (p *Processor) executeSyftScans(pods []libk8s.PodInfo, allImages []*liboci. targetImages := t.LoadImages() removableImages := make([]*liboci.RegistryImage, 0) for _, t := range targetImages { + err := kubernetes.ApplyProxyRegistry(t, false, libstandard.ToMap(internal.OperatorConfig.RegistryProxies)) + if err != nil { + logrus.WithError(err).Debugf("Could not parse image") + } + if !containsImage(allImages, t.ImageID) { removableImages = append(removableImages, t) delete(p.imageMap, t.ImageID) @@ -276,6 +282,11 @@ func (p *Processor) cleanupImagesIfNeeded(removedContainers []*libk8s.ContainerI for _, po := range allPods { pod := po.(*corev1.Pod) info := p.K8s.Client.ExtractPodInfos(*pod) + err := kubernetes.ApplyProxyRegistry(c.Image, false, libstandard.ToMap(internal.OperatorConfig.RegistryProxies)) + if err != nil { + logrus.WithError(err).Debugf("Could not parse image") + } + found = found || containsContainerImage(info.Containers, c.Image.ImageID) } diff --git a/internal/syft/syft.go b/internal/syft/syft.go index 2f497a87..4e3f42ef 100644 --- a/internal/syft/syft.go +++ b/internal/syft/syft.go @@ -12,10 +12,8 @@ import ( "github.com/anchore/syft/syft/source" "github.com/ckotzbauer/libk8soci/pkg/oci" + "github.com/ckotzbauer/sbom-operator/internal/kubernetes" "github.com/sirupsen/logrus" - - parser "github.com/novln/docker-parser" - "github.com/novln/docker-parser/docker" ) type Syft struct { @@ -39,7 +37,7 @@ func (s Syft) WithVersion(version string) Syft { func (s *Syft) ExecuteSyft(img *oci.RegistryImage) (string, error) { logrus.Infof("Processing image %s", img.ImageID) - err := s.ApplyProxyRegistry(img) + err := kubernetes.ApplyProxyRegistry(img, true, s.proxyRegistryMap) if err != nil { return "", err } @@ -123,30 +121,3 @@ func getSyftVersion() string { return "" } - -func (s *Syft) ApplyProxyRegistry(img *oci.RegistryImage) error { - imageRef, err := parser.Parse(img.ImageID) - if err != nil { - logrus.WithError(err).Errorf("Could not parse image %s", img.ImageID) - return err - } - - for registryToReplace, proxyRegistry := range s.proxyRegistryMap { - if imageRef.Registry() == registryToReplace { - shortName := strings.TrimPrefix(imageRef.ShortName(), docker.DefaultRepoPrefix) - fullName := fmt.Sprintf("%s/%s", imageRef.Registry(), shortName) - if strings.HasPrefix(imageRef.Tag(), "sha256") { - fullName = fmt.Sprintf("%s@%s", fullName, imageRef.Tag()) - } else { - fullName = fmt.Sprintf("%s:%s", fullName, imageRef.Tag()) - } - - img.ImageID = strings.ReplaceAll(fullName, registryToReplace, proxyRegistry) - img.Image = strings.ReplaceAll(img.Image, registryToReplace, proxyRegistry) - logrus.Debugf("Applied Registry-Proxy %s", img.ImageID) - break - } - } - - return nil -} diff --git a/internal/syft/syft_test.go b/internal/syft/syft_test.go index 881d166e..99ae0d90 100644 --- a/internal/syft/syft_test.go +++ b/internal/syft/syft_test.go @@ -17,12 +17,6 @@ type simpleTestData struct { expected string } -type mapTestData struct { - input string - expected string - dataMap map[string]string -} - type testData struct { image string digest string @@ -257,48 +251,3 @@ func TestGetFileName(t *testing.T) { }) } } - -func TestApplyProxyRegistry(t *testing.T) { - tests := []mapTestData{ - { - input: "alpine:3.17", - expected: "alpine:3.17", - dataMap: make(map[string]string), - }, - { - input: "docker.io/alpine:3.17", - expected: "ghcr.io/alpine:3.17", - dataMap: map[string]string{"docker.io": "ghcr.io"}, - }, - { - input: "alpine:3.17", - expected: "ghcr.io/alpine:3.17", - dataMap: map[string]string{"docker.io": "ghcr.io"}, - }, - { - input: "alpine:3.17", - expected: "alpine:3.17", - dataMap: map[string]string{"ghcr.io": "docker.io"}, - }, - { - input: "alpine:3.17", - expected: "my.registry.com:5000/alpine:3.17", - dataMap: map[string]string{"docker.io": "my.registry.com:5000"}, - }, - { - input: "my.registry.com:5000/alpine:3.17", - expected: "ghcr.io/alpine:3.17", - dataMap: map[string]string{"my.registry.com:5000": "ghcr.io"}, - }, - } - - for _, v := range tests { - t.Run(v.input, func(t *testing.T) { - s := syft.New("json", v.dataMap) - img := &oci.RegistryImage{ImageID: v.input, Image: v.input} - err := s.ApplyProxyRegistry(img) - assert.NoError(t, err) - assert.Equal(t, v.expected, img.ImageID) - }) - } -}