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

refactor: packager inspect command #2990

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
42 changes: 33 additions & 9 deletions src/cmd/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/zarf-dev/zarf/src/pkg/packager"
"github.com/zarf-dev/zarf/src/pkg/packager/filters"
"github.com/zarf-dev/zarf/src/pkg/packager/sources"
"github.com/zarf-dev/zarf/src/pkg/utils"
"github.com/zarf-dev/zarf/src/types"
)

Expand Down Expand Up @@ -188,26 +189,49 @@ var packageInspectCmd = &cobra.Command{
}
},
RunE: func(cmd *cobra.Command, args []string) error {
packageSource, err := choosePackage(args)
src, err := choosePackage(args)
if err != nil {
return err
}
pkgConfig.PkgOpts.PackageSource = packageSource
src, err := identifyAndFallbackToClusterSource()
if err != nil {
return err

loadOpt := packager2.LoadOptions{
Source: src,
Shasum: pkgConfig.PkgOpts.Shasum,
PublicKeyPath: pkgConfig.PkgOpts.PublicKeyPath,
SkipSignatureValidation: pkgConfig.PkgOpts.SkipSignatureValidation,
Filter: filters.Empty(),
}
pkgClient, err := packager.New(&pkgConfig, packager.WithSource(src))

pkgPaths, err := packager2.LoadPackage(cmd.Context(), loadOpt)
if err != nil {
return err
}
defer pkgClient.ClearTempPaths()
if err := pkgClient.Inspect(cmd.Context()); err != nil {
defer os.RemoveAll(pkgPaths.Base)

inspectOpt := packager2.ZarfInspectOptions{
PackagePaths: pkgPaths,
ListImages: pkgConfig.InspectOpts.ListImages,
ViewSBOM: pkgConfig.InspectOpts.ViewSBOM,
SBOMOutputDir: pkgConfig.InspectOpts.SBOMOutputDir,
}

if pkgConfig.InspectOpts.ListImages {
output, err := packager2.InspectList(cmd.Context(), inspectOpt)
if err != nil {
return fmt.Errorf("failed to inspect package: %w", err)
}
for _, image := range output {
fmt.Fprintln(os.Stdout, "-", image)
}
}

output, err := packager2.Inspect(cmd.Context(), inspectOpt)
if err != nil {
return fmt.Errorf("failed to inspect package: %w", err)
}
utils.ColorPrintYAML(output, nil, false)
return nil
},
ValidArgsFunction: getPackageCompletionArgs,
}

var packageListCmd = &cobra.Command{
Expand Down
104 changes: 104 additions & 0 deletions src/internal/packager2/inspect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors

// Package packager2 contains functions for inspecting packages.
package packager2

import (
"context"
"fmt"

"github.com/defenseunicorns/pkg/helpers/v2"
"github.com/zarf-dev/zarf/src/api/v1alpha1"
"github.com/zarf-dev/zarf/src/internal/packager/sbom"
"github.com/zarf-dev/zarf/src/pkg/layout"
)

// ZarfInspectOptions tracks the user-defined preferences during a package inspection.
type ZarfInspectOptions struct {
// PackagePaths
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// PackagePaths

PackagePaths *layout.PackagePaths
// View SBOM contents while inspecting the package
ViewSBOM bool
// Location to output an SBOM into after package inspection
SBOMOutputDir string
// ListImages will list the images in the package
ListImages bool
}

// Inspect list the contents of a package.
func Inspect(ctx context.Context, options ZarfInspectOptions) (v1alpha1.ZarfPackage, error) {
var err error
pkg, err := getPackageMetadata(ctx, options.PackagePaths)
if err != nil {
return pkg, err
}

if getSBOM(options.ViewSBOM, options.SBOMOutputDir) {
err = handleSBOMOptions(options.PackagePaths, pkg, options.ViewSBOM, options.SBOMOutputDir)
if err != nil {
return pkg, err
}
return pkg, nil
}
return pkg, nil
}

// InspectList lists the images in a component action
func InspectList(ctx context.Context, options ZarfInspectOptions) ([]string, error) {
var imageList []string
pkg, err := getPackageMetadata(ctx, options.PackagePaths)
if err != nil {
return nil, err
}
// Only list images if we have have components
if len(pkg.Components) > 0 {
for _, component := range pkg.Components {
imageList = append(imageList, component.Images...)
}
if len(imageList) > 0 {
imageList = helpers.Unique(imageList)
return imageList, nil
}
return nil, fmt.Errorf("failed listing images: list of images found in components: %d", len(imageList))
}

return imageList, err
}

func getPackageMetadata(_ context.Context, layout *layout.PackagePaths) (v1alpha1.ZarfPackage, error) {
pkg, _, err := layout.ReadZarfYAML()
if err != nil {
return pkg, err
}
return pkg, nil
}

func handleSBOMOptions(layout *layout.PackagePaths, pkg v1alpha1.ZarfPackage, viewSBOM bool, SBOMOutputDir string) error {
if SBOMOutputDir != "" {
out, err := layout.SBOMs.OutputSBOMFiles(SBOMOutputDir, pkg.Metadata.Name)
if err != nil {
return err
}
if viewSBOM {
err := sbom.ViewSBOMFiles(out)
if err != nil {
return err
}
}
} else if viewSBOM {
err := sbom.ViewSBOMFiles(layout.SBOMs.Path)
if err != nil {
return err
}
return err
}
return nil
}

func getSBOM(viewSBOM bool, SBOMOutputDir string) bool {
if viewSBOM || SBOMOutputDir != "" {
return true
}
return false
}
2 changes: 1 addition & 1 deletion src/internal/packager2/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func LoadPackage(ctx context.Context, opt LoadOptions) (*layout.PackagePaths, er
if err := sources.ValidatePackageIntegrity(pkgPaths, pkg.Metadata.AggregateChecksum, isPartial); err != nil {
return nil, err
}
if opt.SkipSignatureValidation {
if !opt.SkipSignatureValidation {
if err := sources.ValidatePackageSignature(ctx, pkgPaths, opt.PublicKeyPath); err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion src/pkg/packager/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (p *Packager) Inspect(ctx context.Context) error {
}
p.cfg.Pkg = pkg

if p.cfg.InspectOpts.ListImages {
if p.cfg.InspectOpts.ListImages && len(p.cfg.Pkg.Components) > 0 {
imageList := []string{}
for _, component := range p.cfg.Pkg.Components {
imageList = append(imageList, component.Images...)
Expand Down
10 changes: 0 additions & 10 deletions src/test/e2e/00_use_cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,16 +154,6 @@ func TestUseCLI(t *testing.T) {
require.Greater(t, len(files), 1)
})

// TODO: Refactor test as it depends on debug log output for validation.
t.Run("zarf package inspect with tmpdir", func(t *testing.T) {
t.Parallel()
path := fmt.Sprintf("build/zarf-package-component-actions-%s.tar.zst", e2e.Arch)
tmpdir := t.TempDir()
stdOut, stdErr, err := e2e.Zarf(t, "package", "inspect", path, "--tmpdir", tmpdir, "--log-level=debug")
require.Contains(t, stdErr, tmpdir, "The other tmp path should show as being created")
require.NoError(t, err, stdOut, stdErr)
})

// TODO: Refactor test as it depends on debug log output for validation.
t.Run("zarf package deploy with tmpdir", func(t *testing.T) {
t.Parallel()
Expand Down
6 changes: 0 additions & 6 deletions src/test/e2e/31_checksum_and_signature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,9 @@ func TestChecksumAndSignature(t *testing.T) {
require.NoError(t, err, stdOut, stdErr)
defer e2e.CleanFiles(pkgName)

/* Test operations during package inspect */
// Test that we can inspect the yaml of the package without the private key
stdOut, stdErr, err = e2e.Zarf(t, "package", "inspect", pkgName)
require.NoError(t, err, stdOut, stdErr)

// Test that we don't get an error when we remember to provide the public key
stdOut, stdErr, err = e2e.Zarf(t, "package", "inspect", pkgName, publicKeyFlag)
require.NoError(t, err, stdOut, stdErr)
require.Contains(t, stdErr, "Verified OK")

/* Test operations during package deploy */
// Test that we get an error when trying to deploy a package without providing the public key
Expand Down
Loading