Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 25 additions & 17 deletions sensor/kubernetes/listener/resources/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,13 @@ func (w *deploymentWrap) populateImageMetadata(localImages set.StringSet, pods .
// The downside to this is that if different pods have different versions then we will miss that fact that pods are running
// different versions and clobber it. I've added a log to illustrate the clobbering so we can see how often it happens

// Sort the w.Deployment.Containers by name and p.Status.ContainerStatuses by name
// This is because the order is not guaranteed
sort.SliceStable(w.GetDeployment().GetContainers(), func(i, j int) bool {
return w.GetDeployment().GetContainers()[i].GetName() < w.GetDeployment().GetContainers()[j].GetName()
})
// Build a map from container name to deployment container for name-based matching.
// This avoids index-based alignment which breaks when other container types are
// present in deployment.Containers but not in pod container statuses.
containersByName := make(map[string]*storage.Container, len(w.GetDeployment().GetContainers()))
for _, c := range w.GetDeployment().GetContainers() {
containersByName[c.GetName()] = c
}

// Sort the pods by time created as that pod will be most likely to have the most updated spec
sort.SliceStable(pods, func(i, j int) bool {
Expand All @@ -323,19 +325,20 @@ func (w *deploymentWrap) populateImageMetadata(localImages set.StringSet, pods .

// Determine each image's ID, if not already populated, as well as if the image is pullable and/or cluster-local.
for _, p := range pods {
sort.SliceStable(p.Status.ContainerStatuses, func(i, j int) bool {
return p.Status.ContainerStatuses[i].Name < p.Status.ContainerStatuses[j].Name
})
sort.SliceStable(p.Spec.Containers, func(i, j int) bool {
return p.Spec.Containers[i].Name < p.Spec.Containers[j].Name
})
for i, c := range p.Status.ContainerStatuses {
if i >= len(w.GetDeployment().GetContainers()) || i >= len(p.Spec.Containers) {
// This should not happen, but could happen if w.Deployment.Containers and container status are out of sync
break
// Build a map from container name to pod spec container for name-based lookup.
specContainersByName := make(map[string]v1.Container, len(p.Spec.Containers))
for _, sc := range p.Spec.Containers {
specContainersByName[sc.Name] = sc
}

for _, c := range p.Status.ContainerStatuses {
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
deployContainer, found := containersByName[c.Name]
if !found {
log.Debugf("Skipping container status %q with no matching deployment container for deploy %q, pod %q", c.Name, w.GetDeployment().GetName(), p.GetName())
continue
}

image := w.GetDeployment().GetContainers()[i].GetImage()
image := deployContainer.GetImage()

var runtimeImageName *storage.ImageName
if features.UnqualifiedSearchRegistries.Enabled() && c.ImageID != "" {
Expand Down Expand Up @@ -365,7 +368,12 @@ func (w *deploymentWrap) populateImageMetadata(localImages set.StringSet, pods .
continue
}

parsedName, err := imageUtils.GenerateImageFromStringWithOverride(p.Spec.Containers[i].Image, w.registryOverride)
specContainer, found := specContainersByName[c.Name]
if !found {
continue
}

parsedName, err := imageUtils.GenerateImageFromStringWithOverride(specContainer.Image, w.registryOverride)
if err != nil {
// This error will only happen if we could not parse the image, this is possible if the image in kubernetes is malformed
// e.g. us.gcr.io/$PROJECT/xyz:latest is an example that we have seen
Expand Down
29 changes: 19 additions & 10 deletions sensor/kubernetes/listener/resources/convert_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package resources

import (
"fmt"
"testing"
"time"

Expand Down Expand Up @@ -390,23 +391,27 @@ func TestPopulateImageMetadata(t *testing.T) {
wrap := deploymentWrap{
Deployment: &storage.Deployment{},
}
for _, container := range c.wrap {
for i, container := range c.wrap {
name := fmt.Sprintf("container-%d", i)
img, err := imageUtils.GenerateImageFromString(container.image)
require.NoError(t, err)
wrap.Containers = append(wrap.Containers, &storage.Container{
Name: name,
Image: img,
})

}

pods := make([]*v1.Pod, 0, len(c.pods))
for _, pod := range c.pods {
k8sPod := &v1.Pod{}
for _, img := range pod.images {
k8sPod.Spec.Containers = append(k8sPod.Spec.Containers, v1.Container{Image: img})
for i, img := range pod.images {
name := fmt.Sprintf("container-%d", i)
k8sPod.Spec.Containers = append(k8sPod.Spec.Containers, v1.Container{Name: name, Image: img})
}
for _, imageID := range pod.imageIDsInStatus {
for i, imageID := range pod.imageIDsInStatus {
name := fmt.Sprintf("container-%d", i)
k8sPod.Status.ContainerStatuses = append(k8sPod.Status.ContainerStatuses, v1.ContainerStatus{
Name: name,
ImageID: imageID,
})
}
Expand Down Expand Up @@ -545,23 +550,27 @@ func TestPopulateImageMetadataWithUnqualified(t *testing.T) {
wrap := deploymentWrap{
Deployment: &storage.Deployment{},
}
for _, container := range c.wrap {
for i, container := range c.wrap {
name := fmt.Sprintf("container-%d", i)
img, err := imageUtils.GenerateImageFromString(container.image)
require.NoError(t, err)
wrap.Containers = append(wrap.Containers, &storage.Container{
Name: name,
Image: img,
})

}

pods := make([]*v1.Pod, 0, len(c.pods))
for _, pod := range c.pods {
k8sPod := &v1.Pod{}
for _, img := range pod.images {
k8sPod.Spec.Containers = append(k8sPod.Spec.Containers, v1.Container{Image: img})
for i, img := range pod.images {
name := fmt.Sprintf("container-%d", i)
k8sPod.Spec.Containers = append(k8sPod.Spec.Containers, v1.Container{Name: name, Image: img})
}
for _, imageID := range pod.imageIDsInStatus {
for i, imageID := range pod.imageIDsInStatus {
name := fmt.Sprintf("container-%d", i)
k8sPod.Status.ContainerStatuses = append(k8sPod.Status.ContainerStatuses, v1.ContainerStatus{
Name: name,
ImageID: imageID,
})
}
Expand Down
Loading