Skip to content

Commit

Permalink
WIP: refactoring approach, still need local pkgs
Browse files Browse the repository at this point in the history
  • Loading branch information
UncleGedd committed Jun 4, 2024
1 parent 0605b37 commit 277681b
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 141 deletions.
1 change: 0 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ repos:
hooks:
- id: golangci-lint-full
args: [--timeout=5m]
linters:
- repo: local
hooks:
- id: check-docs-and-schema
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/uds.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func init() {
inspectCmd.Flags().BoolVarP(&bundleCfg.InspectOpts.IncludeSBOM, "sbom", "s", false, lang.CmdPackageInspectFlagSBOM)
inspectCmd.Flags().BoolVarP(&bundleCfg.InspectOpts.ExtractSBOM, "extract", "e", false, lang.CmdPackageInspectFlagExtractSBOM)
inspectCmd.Flags().StringVarP(&bundleCfg.InspectOpts.PublicKeyPath, "key", "k", v.GetString(V_BNDL_INSPECT_KEY), lang.CmdBundleInspectFlagKey)
inspectCmd.Flags().BoolVarP(&bundleCfg.InspectOpts.ExtractImages, "list-images", "i", false, "Recursively go through all of the sbom's and get the images")
inspectCmd.Flags().BoolVarP(&bundleCfg.InspectOpts.ListImages, "list-images", "i", false, lang.CmdBundleInspectFlagFindImages)

// remove cmd flags
rootCmd.AddCommand(removeCmd)
Expand Down
1 change: 1 addition & 0 deletions src/config/lang/lang.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const (
CmdBundleInspectFlagKey = "Path to a public key file that will be used to validate a signed bundle"
CmdPackageInspectFlagSBOM = "Create a tarball of SBOMs contained in the bundle"
CmdPackageInspectFlagExtractSBOM = "Create a folder of SBOMs contained in the bundle"
CmdBundleInspectFlagFindImages = "Find all images in the bundle"

// bundle remove
CmdBundleRemoveShort = "Remove a bundle that has been deployed already"
Expand Down
184 changes: 71 additions & 113 deletions src/pkg/bundle/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,88 +5,43 @@
package bundle

import (
"bytes"
"os"
"os/exec"
"fmt"
"path/filepath"
"strings"

"github.com/defenseunicorns/pkg/oci"
"github.com/defenseunicorns/uds-cli/src/config"
"github.com/defenseunicorns/uds-cli/src/pkg/utils"
"github.com/defenseunicorns/zarf/src/pkg/layout"
"github.com/defenseunicorns/zarf/src/pkg/packager/filters"
zarfSources "github.com/defenseunicorns/zarf/src/pkg/packager/sources"
zarfUtils "github.com/defenseunicorns/zarf/src/pkg/utils"
"github.com/defenseunicorns/zarf/src/pkg/message"
"github.com/defenseunicorns/zarf/src/pkg/utils"
"gopkg.in/yaml.v2"
"github.com/defenseunicorns/zarf/src/pkg/zoci"
zarfTypes "github.com/defenseunicorns/zarf/src/types"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)

func (b *Bundle) extractImagesFromPackages() {
for i, pkg := range b.bundle.Packages {
if pkg.Repository != "" && pkg.Ref != "" {
message.Debugf("Package: %s, Repository: %s, Ref: %s", pkg.Name, pkg.Repository, pkg.Ref)
type Component struct {
Images []string `yaml:"images"`
}

type Output struct {
Components []Component `yaml:"components"`
}

cmd := exec.Command("uds", "zarf", "package", "inspect", "oci://"+pkg.Repository+":"+pkg.Ref, "--no-color", "--no-log-file")

var output bytes.Buffer
cmd.Stdout = &output
cmd.Stderr = &output

err := cmd.Run() // Use Run instead of CombinedOutput
if err != nil {
message.Fatalf("Error executing command: %s, output: %s", err.Error(), output.String())
continue
}
outputStr := output.String()

// Find the index of "kind:"
idx := strings.Index(outputStr, "kind:")
if idx == -1 {
message.Fatalf("Invalid output: %s", outputStr)
continue
}

// Trim the output
trimmedOutput := outputStr[idx:]

message.Debugf("Trimmed Output: %s", trimmedOutput)

var result interface{}
err = yaml.Unmarshal([]byte(trimmedOutput), &result)
if err != nil {
message.Fatalf("Error unmarshaling YAML: %s", err.Error())
continue
}

var allImages []string
findImages(result, &allImages)

// Add the images to the package
if len(allImages) > 0 {
message.Debugf("Images: %v", allImages)
b.bundle.Packages[i].Images = allImages
} else {
message.Debugf("No images found in package %v", pkg.Name)
}
}
}
}

// Inspect pulls/unpacks a bundle's metadata and shows it
func (b *Bundle) Inspect() error {
// Check if the source is a YAML file
if filepath.Ext(b.cfg.InspectOpts.Source) == ".yaml" {
if b.cfg.InspectOpts.ListImages && filepath.Ext(b.cfg.InspectOpts.Source) == ".yaml" { // todo: or .yml
source, err := CheckYAMLSourcePath(b.cfg.InspectOpts.Source)
if err != nil {
return err
}
b.cfg.InspectOpts.Source = source
return b.InspectYAML(b.cfg.InspectOpts.Source)

// read the bundle's metadata into memory
if err := utils.ReadYAMLStrict(b.cfg.InspectOpts.Source, &b.bundle); err != nil {
return err
}

imgs, err := b.extractImagesFromPackages()
if err != nil {
return err
}
fmt.Println(strings.Join(imgs, "\n"))
return nil
}

// Check that provided oci source path is valid, and update it if it's missing the full path
Expand Down Expand Up @@ -124,13 +79,6 @@ func (b *Bundle) Inspect() error {
if err := utils.ReadYAMLStrict(loaded[config.BundleYAML], &b.bundle); err != nil {
return err
}
// If ExtractImages flag is set, extract images from each package
if b.cfg.InspectOpts.ExtractImages {
message.Debugf("Extracting images from packages")
b.extractImagesFromPackages()
} else {
message.Debugf("Skipping image extraction")
}

// show the bundle's metadata
zarfUtils.ColorPrintYAML(b.bundle, nil, false)
Expand All @@ -140,52 +88,62 @@ func (b *Bundle) Inspect() error {
return nil
}

// InspectYAML inspects a bundle from a YAML file
func (b *Bundle) InspectYAML(yamlPath string) error {
message.Debugf("Reading the yaml file: %s", yamlPath)
// Read the YAML file
data, err := os.ReadFile(yamlPath)
if err != nil {
return err
}
func (b *Bundle) extractImagesFromPackages() ([]string, error) {
imgMap := make(map[string]string)
for _, pkg := range b.bundle.Packages {
if pkg.Repository != "" && pkg.Ref != "" {

// Unmarshal the YAML data into the Bundle struct
err = yaml.Unmarshal(data, &b.bundle)
if err != nil {
return err
}
url := fmt.Sprintf("oci://%s:%s", pkg.Repository, pkg.Ref)
platform := ocispec.Platform{
Architecture: config.GetArch(),
OS: oci.MultiOS,
}
remote, err := zoci.NewRemote(url, platform)
if err != nil {
return nil, err
}

// If ExtractImages flag is set, extract images from each package
if b.cfg.InspectOpts.ExtractImages {
b.extractImagesFromPackages()
}
source := zarfSources.OCISource{
ZarfPackageOptions: &zarfTypes.ZarfPackageOptions{
PublicKeyPath: "",
},
Remote: remote,
}

// show the bundle's metadata
utils.ColorPrintYAML(b.bundle, nil, false)
return nil
}
tmpDir, err := zarfUtils.MakeTempDir(config.CommonOptions.TempDirectory)
if err != nil {
return nil, err
}
pkgPaths := layout.New(tmpDir)
zarfPkg, _, err := source.LoadPackageMetadata(pkgPaths, false, true)
if err != nil {
return nil, err
}

// create filter for optional components
inspectFilter := filters.Combine(
filters.ForDeploy(strings.Join(pkg.OptionalComponents, ","), false),
)

func findImages(node interface{}, images *[]string) {
switch node := node.(type) {
case map[interface{}]interface{}:
for k, v := range node {
if k == "images" {
// Check if v is a slice of interfaces
if imgSlice, ok := v.([]interface{}); ok {
// Convert each element to a string and append it to images
for _, img := range imgSlice {
if imgStr, ok := img.(string); ok {
*images = append(*images, imgStr)
}
}
filteredComponents, err := inspectFilter.Apply(zarfPkg)
if err != nil {
return nil, err
}

// grab images from each filtered component
for _, component := range filteredComponents {
for _, img := range component.Images {
imgMap[img] = img
}
} else {
findImages(v, images)
}
}
case []interface{}:
for _, v := range node {
findImages(v, images)
}
}

// convert img map to list of strings
var images []string
for _, img := range imgMap {
images = append(images, img)
}

return images, nil
}
24 changes: 12 additions & 12 deletions src/test/bundles/14-optional-components/uds-bundle.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ packages:
ref: v0.34.0

# deploys prometheus as a required component and upload-image as an optional component (with noOptionalComponents key)
- name: prometheus
repository: localhost:888/prometheus
ref: 0.0.1
optionalComponents:
- upload-image

# deploys podinfo as an optional component and apache as a required component
- name: podinfo-nginx
path: ../../packages/podinfo-nginx
ref: 0.0.1
optionalComponents:
- podinfo
# - name: prometheus
# repository: localhost:888/prometheus
# ref: 0.0.1
# optionalComponents:
# - upload-image
#
# # deploys podinfo as an optional component and apache as a required component
# - name: podinfo-nginx
# path: ../../packages/podinfo-nginx
# ref: 0.0.1
# optionalComponents:
# - podinfo
13 changes: 0 additions & 13 deletions src/test/e2e/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ import (
"testing"

"github.com/defenseunicorns/pkg/helpers/v2"
"gopkg.in/yaml.v2"

"github.com/defenseunicorns/pkg/helpers"
"github.com/defenseunicorns/uds-cli/src/config"
"github.com/defenseunicorns/zarf/src/pkg/message"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
Expand Down Expand Up @@ -114,16 +111,6 @@ func inspectLocalAndSBOMExtract(t *testing.T, tarballPath string) {
require.NoError(t, err)
}

func inspectBundleYAML(t *testing.T, yamlPath string) {
cmd := strings.Split(fmt.Sprintf("inspect %s", yamlPath), " ")
_, _, err := e2e.UDS(cmd...)
data, err := os.ReadFile(yamlPath)
require.NoError(t, err)
var bundleData map[string]interface{}
err = yaml.Unmarshal(data, &bundleData)
require.NoError(t, err)
}

func deploy(t *testing.T, tarballPath string) (stdout string, stderr string) {
cmd := strings.Split(fmt.Sprintf("deploy %s --retries 1 --confirm", tarballPath), " ")
stdout, stderr, err := e2e.UDS(cmd...)
Expand Down
2 changes: 1 addition & 1 deletion src/types/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ type BundleInspectOptions struct {
Source string
IncludeSBOM bool
ExtractSBOM bool
ExtractImages bool
ListImages bool
}

// BundlePublishOptions is the options for the bundle.Publish() function
Expand Down

0 comments on commit 277681b

Please sign in to comment.