Skip to content

Commit

Permalink
fix: pod spec hash issues when using image mirroring (#1205)
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigorfk committed May 7, 2023
1 parent bc57ecc commit 56b96bb
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 12 deletions.
12 changes: 12 additions & 0 deletions pkg/kube/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ func GetContainerImagesFromPodSpec(spec corev1.PodSpec) ContainerImages {
return images
}

// GetContainerImagesFromContainersList returns a map of container names
// to container images from the specified corev1.Container array.
func GetContainerImagesFromContainersList(containers []corev1.Container) ContainerImages {
images := ContainerImages{}

for _, container := range containers {
images[container.Name] = container.Image
}

return images
}

// GetContainerImagesFromJob returns a map of container names
// to container images from the specified v1.Job.
// The mapping is encoded as JSON value of the AnnotationContainerImages
Expand Down
34 changes: 34 additions & 0 deletions pkg/kube/resources_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,40 @@ func TestGetContainerImagesFromPodSpec(t *testing.T) {
}, images)
}

func TestGetContainerImagesFromContainersList(t *testing.T) {
images := kube.GetContainerImagesFromContainersList(
[]corev1.Container{
{
Name: "nginx",
Image: "nginx:1.16",
},
{
Name: "sidecar",
Image: "sidecar:1.32.7",
},
{
Name: "init",
Image: "init:1.0.0",
},
{
Name: "init2",
Image: "init:1.0.0",
},
{
Name: "debug",
Image: "debug:1.0.0",
},
},
)
assert.Equal(t, kube.ContainerImages{
"nginx": "nginx:1.16",
"sidecar": "sidecar:1.32.7",
"init": "init:1.0.0",
"init2": "init:1.0.0",
"debug": "debug:1.0.0",
}, images)
}

func TestGetContainerImagesFromJob(t *testing.T) {

t.Run("Should return error when annotation is not set", func(t *testing.T) {
Expand Down
25 changes: 13 additions & 12 deletions pkg/plugins/trivy/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -570,8 +570,7 @@ func (p *plugin) GetScanJobSpec(ctx trivyoperator.PluginContext, workload client
return podSpec, secrets, err
}

func (p *plugin) newSecretWithAggregateImagePullCredentials(obj client.Object, spec corev1.PodSpec, credentials map[string]docker.Auth) *corev1.Secret {
containerImages := kube.GetContainerImagesFromPodSpec(spec)
func (p *plugin) newSecretWithAggregateImagePullCredentials(obj client.Object, containerImages kube.ContainerImages, credentials map[string]docker.Auth) *corev1.Secret {
secretData := kube.AggregateImagePullSecretsData(containerImages, credentials)

return &corev1.Secret{
Expand Down Expand Up @@ -611,28 +610,29 @@ const (
func (p *plugin) getPodSpecForStandaloneMode(ctx trivyoperator.PluginContext, config Config, workload client.Object, credentials map[string]docker.Auth, securityContext *corev1.SecurityContext) (corev1.PodSpec, []*corev1.Secret, error) {
var secret *corev1.Secret
var secrets []*corev1.Secret
var containersSpec []corev1.Container

spec, err := kube.GetPodSpec(workload)
if err != nil {
return corev1.PodSpec{}, nil, err
}

containersSpec := getContainers(spec)
for i := 0; i < len(containersSpec); i++ {
c := &containersSpec[i]
for _, c := range getContainers(spec) {
optionalMirroredImage, err := GetMirroredImage(c.Image, config.GetMirrors())
if err != nil {
return corev1.PodSpec{}, nil, err
}
c.Image = optionalMirroredImage
containersSpec = append(containersSpec, c)
}

containersCredentials, err := kube.MapContainerNamesToDockerAuths(kube.GetContainerImagesFromPodSpec(spec), credentials)
containerImages := kube.GetContainerImagesFromContainersList(containersSpec)
containersCredentials, err := kube.MapContainerNamesToDockerAuths(containerImages, credentials)
if err != nil {
return corev1.PodSpec{}, nil, err
}
if len(containersCredentials) > 0 {
secret = p.newSecretWithAggregateImagePullCredentials(workload, spec, containersCredentials)
secret = p.newSecretWithAggregateImagePullCredentials(workload, containerImages, containersCredentials)
secrets = append(secrets, secret)
}

Expand Down Expand Up @@ -848,6 +848,7 @@ func (p *plugin) initContainerEnvVar(trivyConfigName string, config Config) []co
func (p *plugin) getPodSpecForClientServerMode(ctx trivyoperator.PluginContext, config Config, workload client.Object, credentials map[string]docker.Auth, securityContext *corev1.SecurityContext) (corev1.PodSpec, []*corev1.Secret, error) {
var secret *corev1.Secret
var secrets []*corev1.Secret
var containersSpec []corev1.Container
spec, err := kube.GetPodSpec(workload)
if err != nil {
return corev1.PodSpec{}, nil, err
Expand All @@ -863,22 +864,22 @@ func (p *plugin) getPodSpecForClientServerMode(ctx trivyoperator.PluginContext,
return corev1.PodSpec{}, nil, err
}

containersSpec := getContainers(spec)
for i := 0; i < len(containersSpec); i++ {
c := &containersSpec[i]
for _, c := range getContainers(spec) {
optionalMirroredImage, err := GetMirroredImage(c.Image, config.GetMirrors())
if err != nil {
return corev1.PodSpec{}, nil, err
}
c.Image = optionalMirroredImage
containersSpec = append(containersSpec, c)
}

containersCredentials, err := kube.MapContainerNamesToDockerAuths(kube.GetContainerImagesFromPodSpec(spec), credentials)
containerImages := kube.GetContainerImagesFromContainersList(containersSpec)
containersCredentials, err := kube.MapContainerNamesToDockerAuths(containerImages, credentials)
if err != nil {
return corev1.PodSpec{}, nil, err
}
if len(containersCredentials) > 0 {
secret = p.newSecretWithAggregateImagePullCredentials(workload, spec, containersCredentials)
secret = p.newSecretWithAggregateImagePullCredentials(workload, containerImages, containersCredentials)
secrets = append(secrets, secret)
}

Expand Down
1 change: 1 addition & 0 deletions pkg/plugins/trivy/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6843,6 +6843,7 @@ default ignore = false`,
for i := 0; i < len(secrets); i++ {
assert.Equal(t, tc.expectedSecretsData[i], secrets[i].Data)
}

})
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/vulnerabilityreport/controller/scanjob.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ func (r *ScanJobController) processCompleteScanJob(ctx context.Context, job *bat
return fmt.Errorf("expected label %s not set", trivyoperator.LabelResourceSpecHash)
}

log = log.WithValues("kind", owner.GetObjectKind().GroupVersionKind().Kind,
"name", owner.GetName(), "namespace", owner.GetNamespace(), "podSpecHash", podSpecHash)

log.V(1).Info("Job complete")

hasReports, err := hasReports(ctx, r.ExposedSecretReadWriter, r.VulnerabilityReadWriter, ownerRef, podSpecHash, containerImages)
if err != nil {
return err
Expand Down
4 changes: 4 additions & 0 deletions pkg/vulnerabilityreport/controller/workload.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ func (r *WorkloadController) reconcileWorkload(workloadKind kube.Kind) reconcile
return ctrl.Result{RequeueAfter: r.Config.ScanJobRetryAfter}, nil
}
}
log.V(1).Info("Submitting a scan for the workload")
// sync all potential workload for scanning
r.SubmitScanJobChan <- ScanJobRequest{Workload: workloadObj, Context: ctx}
// collect scan job processing results
Expand Down Expand Up @@ -307,6 +308,9 @@ func (r *WorkloadController) submitScanJob(ctx context.Context, owner client.Obj
}
}

log = log.WithValues("podSpecHash", scanJob.Labels[trivyoperator.LabelResourceSpecHash])

log.V(1).Info("Creating scan job for the workload")
err = r.Client.Create(ctx, scanJob)
if err != nil {
if k8sapierror.IsAlreadyExists(err) {
Expand Down

0 comments on commit 56b96bb

Please sign in to comment.