Skip to content

Commit

Permalink
Refactor TrivyOpts to separate BuildKit client options, add documenta…
Browse files Browse the repository at this point in the history
…tion

Extracted BuildKit client configurations from TrivyOpts into a new BkClient struct. Updated related functions and tests to accommodate this change, improving modularity and readability.

Signed-off-by: Miaha Cybersec <[email protected]>
  • Loading branch information
Miaha Cybersec authored and Miaha Cybersec committed Aug 7, 2024
1 parent 1b9c7e7 commit 3941bcc
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 13 deletions.
29 changes: 22 additions & 7 deletions pkg/patch/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ const (
)

type TrivyOpts struct {
BkClient *client.Client
SolveOpt *client.SolveOpt
Image string
Ch chan error
ReportFile string
Expand All @@ -57,6 +55,11 @@ type TrivyOpts struct {
Format string
}

type BkClient struct {
BkClient *client.Client
SolveOpt *client.SolveOpt
}

type BuildStatus struct {
BuildChannel chan *client.SolveStatus
}
Expand Down Expand Up @@ -97,15 +100,23 @@ func removeIfNotDebug(workingFolder string) {
}
}

// patchWithContext patches the user-supplied image, image.
// patchWithContext patches the user-supplied image, image
// reportFile is a vulnerability scan passed in by the user
// userSuppliedPatchTag is a tag set by the user to use for the patched image tag
// workingFolder is the folder used by copa, defaults to system temp folder
// scanner used to generate reportFile, defaults to Trivy
// format is the output format, defaults to openvex
// output is the desired output filepath
// ignoreError defines whether Copa should ignore errors
// bkOpts contains buildkitd options for addresses, CA certs, client certs, and client keys.
func patchWithContext(ctx context.Context, ch chan error, image, reportFile, userSuppliedPatchTag, workingFolder, scanner, format, output string, ignoreError bool, bkOpts buildkit.Opts) error {
dockerNormalizedImageName, err := reference.ParseNormalizedNamed(image)

Check warning on line 113 in pkg/patch/patch.go

View check run for this annotation

Codecov / codecov/patch

pkg/patch/patch.go#L112-L113

Added lines #L112 - L113 were not covered by tests
if err != nil {
return err
}

if reference.IsNameOnly(dockerNormalizedImageName) {
log.Warnf("Image name has no tag or digest, using latest as tag")
log.Warnf("Image name %s has no tag or digest, defaulting to %s:latest", image, dockerNormalizedImageName)
dockerNormalizedImageName = reference.TagNameOnly(dockerNormalizedImageName)

Check warning on line 120 in pkg/patch/patch.go

View check run for this annotation

Codecov / codecov/patch

pkg/patch/patch.go#L118-L120

Added lines #L118 - L120 were not covered by tests
}

Expand Down Expand Up @@ -183,10 +194,13 @@ func patchWithContext(ctx context.Context, ch chan error, image, reportFile, use
err = buildkitBuild(
BuildContext{ctx},
&TrivyOpts{
bkClient, &solveOpt, image, ch,
image, ch,
reportFile, workingFolder, updates, ignoreError,
output, dockerNormalizedImageName, patchedImageName, format,
},
BkClient{
bkClient, &solveOpt,
},
BuildStatus{buildChannel})

Check warning on line 204 in pkg/patch/patch.go

View check run for this annotation

Codecov / codecov/patch

pkg/patch/patch.go#L194-L204

Added lines #L194 - L204 were not covered by tests
return err
})
Expand Down Expand Up @@ -217,8 +231,9 @@ func patchWithContext(ctx context.Context, ch chan error, image, reportFile, use
return eg.Wait()
}

func buildkitBuild(buildContext BuildContext, trivyOpts *TrivyOpts, buildStatus BuildStatus) error {
_, err := trivyOpts.BkClient.Build(buildContext.Ctx, *trivyOpts.SolveOpt, copaProduct, func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
// buildkitBuild submits a build request to BuildKit with the given information.
func buildkitBuild(buildContext BuildContext, trivyOpts *TrivyOpts, bkClient BkClient, buildStatus BuildStatus) error {
_, err := bkClient.BkClient.Build(buildContext.Ctx, *bkClient.SolveOpt, copaProduct, func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
bkConfig, err := buildkit.InitializeBuildkitConfig(ctx, c, trivyOpts.DockerNormalizedImageName.String())
if err != nil {
return handleError(trivyOpts.Ch, err)

Check warning on line 239 in pkg/patch/patch.go

View check run for this annotation

Codecov / codecov/patch

pkg/patch/patch.go#L235-L239

Added lines #L235 - L239 were not covered by tests
Expand Down
21 changes: 15 additions & 6 deletions pkg/patch/patch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package patch
import (
"context"
"errors"
"fmt"
"io"
"os"
"os/exec"
Expand Down Expand Up @@ -299,6 +300,8 @@ func TestGetOSVersion(t *testing.T) {
}
}

// Test generating a patched tag for an image
// If userSuppliedPatchTag is a blank string, the function defaults to defaultPatchedTagSuffix.
func TestGeneratePatchedTag(t *testing.T) {
testCases := []struct {
name string
Expand All @@ -312,17 +315,23 @@ func TestGeneratePatchedTag(t *testing.T) {
userSuppliedPatchTag: "",
expectedPatchedTag: defaultPatchedTagSuffix,
},
{
name: "NoTag_UserSupplied",
dockerImageName: "docker.io/library/alpine",
userSuppliedPatchTag: "1234",
expectedPatchedTag: "1234",
},
{
name: "WithTag_NoUserSupplied",
dockerImageName: "docker.io/redhat/ubi9:latest",
userSuppliedPatchTag: "",
expectedPatchedTag: "latest-patched",
expectedPatchedTag: fmt.Sprintf("latest-%s", defaultPatchedTagSuffix),
},
{
name: "WithTag_UserSupplied",
dockerImageName: "docker.io/librari/ubuntu:jammy-20231004",
userSuppliedPatchTag: "20231004-patched",
expectedPatchedTag: "20231004-patched",
userSuppliedPatchTag: "20231004-custom-tag",
expectedPatchedTag: "20231004-custom-tag",
},
}

Expand All @@ -337,9 +346,8 @@ func TestGeneratePatchedTag(t *testing.T) {
}
}

// This test simulates the vulnerable packages Trivy supplies to Copa.
func TestUpdateManifest(t *testing.T) {
errPkgs := []string{"package1", "package2", "package3"}

updates := &unversioned.UpdateManifest{
Metadata: unversioned.Metadata{
OS: unversioned.OS{
Expand All @@ -357,6 +365,7 @@ func TestUpdateManifest(t *testing.T) {
},
}

// errPkgs in this struct is used to define which packages would throw an error during the update process
testCases := []struct {
name string
updates *unversioned.UpdateManifest
Expand Down Expand Up @@ -387,7 +396,7 @@ func TestUpdateManifest(t *testing.T) {
{
name: "AllErrorPackages",
updates: updates,
errPkgs: errPkgs,
errPkgs: []string{"package1", "package2", "package3"},
expected: &unversioned.UpdateManifest{
Metadata: unversioned.Metadata{
OS: unversioned.OS{
Expand Down

0 comments on commit 3941bcc

Please sign in to comment.