Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: pod spec hash issues when using image mirroring #1205

Merged
merged 1 commit into from
May 7, 2023
Merged
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
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