Skip to content

Commit

Permalink
changes requested
Browse files Browse the repository at this point in the history
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
  • Loading branch information
arorasoham9 committed Jun 24, 2024
1 parent 57c1b2c commit f4b5590
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 71 deletions.
65 changes: 29 additions & 36 deletions cmd/guacone/cmd/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,9 @@ type AnalyzeOpts struct {
Namespaces bool
URI bool
PURL bool
ID bool
}

var analyzeCmd = &cobra.Command{
var analyzeCmd = &cobra.Command {
Use: "analyze <operation> <sboms> [flags] ",
Short: "analyze is a CLI tool tailored for comparing, intersecting, and merging Software Bill of Materials (SBOMs) within GUAC",
Long: `Diff Analysis: Compare two SBOMs to identify differences in their software components, versions, and dependencies.
Expand All @@ -67,12 +66,12 @@ var analyzeCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {

if len(args) < 1 || len(args) > 1 {
fmt.Println("Required 1 positional arguments, got", len(args))
fmt.Println("required 1 positional arguments, got", len(args))
os.Exit(1)
}

if args[0] != "intersect" && args[0] != "union" && args[0] != "diff" {
fmt.Println("Invalid positional argument. Must be one of: intersect, union or diff.")
fmt.Println("invalid positional argument. Must be one of: intersect, union or diff.")
os.Exit(1)
}

Expand All @@ -91,22 +90,21 @@ var analyzeCmd = &cobra.Command{
inclDeps, _ := cmd.Flags().GetBool("incl-deps")
inclOccur, _ := cmd.Flags().GetBool("incl-occur")
namespaces, _ := cmd.Flags().GetBool("namespaces")
id, _ := cmd.Flags().GetBool("id")
test, _ := cmd.Flags().GetString("test")

var graphs []graph.Graph[string, *analyzer.Node]
var err error

if test == "" {
if err = verifyAnalyzeFlags(slsas, sboms, errSlsa, errSbom, uri, purl, id); err != nil {
fmt.Fprintf(os.Stderr, "Error: %s", err)
if err = validateAnalyzeFlags(slsas, sboms, errSlsa, errSbom, uri, purl); err != nil {
fmt.Fprintf(os.Stderr, "error: %s", err)
_ = cmd.Help()
os.Exit(1)
}

//create graphs
graphs, err = hasSBOMToGraph(ctx, gqlclient, sboms, AnalyzeOpts{
Metadata: metadata, InclSoft: inclSoft, InclDeps: inclDeps, InclOccur: inclOccur, Namespaces: namespaces, URI: uri, PURL: purl, ID: id})
Metadata: metadata, InclSoft: inclSoft, InclDeps: inclDeps, InclOccur: inclOccur,
Namespaces: namespaces, URI: uri, PURL: purl, })

if err != nil {
logger.Fatalf("Unable to generate graphs: %v", err)
Expand Down Expand Up @@ -352,15 +350,6 @@ func hasSBOMToGraph(ctx context.Context, gqlclient graphql.Client, sboms []strin
if err != nil {
return []graph.Graph[string, *analyzer.Node]{}, fmt.Errorf("(purl)failed to lookup sbom: %v %v", sboms[1], err)
}
} else if opts.ID {
hasSBOMResponseOne, err = analyzer.FindHasSBOMBy(model.HasSBOMSpec{}, "", "", sboms[0], ctx, gqlclient)
if err != nil {
return []graph.Graph[string, *analyzer.Node]{}, fmt.Errorf("(id)failed to lookup sbom: %v %v", sboms[0], err)
}
hasSBOMResponseTwo, err = analyzer.FindHasSBOMBy(model.HasSBOMSpec{}, "", "", sboms[1], ctx, gqlclient)
if err != nil {
return []graph.Graph[string, *analyzer.Node]{}, fmt.Errorf("(id)failed to lookup sbom: %v %v", sboms[1], err)
}
}

if hasSBOMResponseOne == nil || hasSBOMResponseTwo == nil {
Expand All @@ -377,7 +366,6 @@ func hasSBOMToGraph(ctx context.Context, gqlclient graphql.Client, sboms []strin
hasSBOMOne := hasSBOMResponseOne.HasSBOM[0]
hasSBOMTwo := hasSBOMResponseTwo.HasSBOM[0]

//create graphs
gOne, err := analyzer.MakeGraph(hasSBOMOne, opts.Metadata, opts.InclSoft, opts.InclDeps, opts.InclOccur, opts.Namespaces)
if err != nil {
logger.Fatalf(err.Error())
Expand All @@ -392,7 +380,7 @@ func hasSBOMToGraph(ctx context.Context, gqlclient graphql.Client, sboms []strin
}, nil
}

func verifyAnalyzeFlags(slsas, sboms []string, errSlsa, errSbom error, uri, purl, id bool) error {
func validateAnalyzeFlags(slsas, sboms []string, errSlsa, errSbom error, uri, purl bool) error {

if (errSlsa != nil && errSbom != nil) || (len(slsas) == 0 && len(sboms) == 0) {
return fmt.Errorf("must specify slsa or sboms")
Expand All @@ -414,11 +402,15 @@ func verifyAnalyzeFlags(slsas, sboms []string, errSlsa, errSbom error, uri, purl
return fmt.Errorf("slsa diff to be implemented")
}

if !uri && !purl && !id {
if sboms[0] == "" || sboms[1] == "" {
return fmt.Errorf("expected sbom received \"\"")
}

if !uri && !purl {
return fmt.Errorf("must provide one of --uri or --purl")
}

if uri && purl || uri && id || purl && id {
if uri && purl {
return fmt.Errorf("must provide only one of --uri or --purl")
}

Expand Down Expand Up @@ -457,20 +449,21 @@ func readTwoSBOM(filename string) ([]graph.Graph[string, *analyzer.Node], error)

func init() {

analyzeCmd.PersistentFlags().StringSlice("sboms", []string{}, "two sboms to analyze")
analyzeCmd.PersistentFlags().StringSlice("slsa", []string{}, "two slsa to analyze")
analyzeCmd.PersistentFlags().Bool("uri", false, "input is a URI")
analyzeCmd.PersistentFlags().Bool("purl", false, "input is a pURL")
analyzeCmd.PersistentFlags().Bool("id", false, "input is an Id")
analyzeCmd.PersistentFlags().Bool("metadata", false, "Compare SBOM metadata")
analyzeCmd.PersistentFlags().Bool("incl-soft", false, "Compare Included Softwares")
analyzeCmd.PersistentFlags().Bool("incl-deps", false, "Compare Included Dependencies")
analyzeCmd.PersistentFlags().Bool("incl-occur", false, "Compare Included Occurrences")
analyzeCmd.PersistentFlags().Bool("namespaces", false, "Compare Package Namespaces")
analyzeCmd.PersistentFlags().Bool("dot", false, "create diff dot file")
analyzeCmd.PersistentFlags().Bool("all", false, " lists all")
analyzeCmd.PersistentFlags().Int("maxprint", 20, "max number of items to print")
analyzeCmd.PersistentFlags().String("test", "", "test file with sbom")
// analyzeCmd.PersistentFlags().StringSlice("sboms", []string{}, "two sboms to analyze")
// analyzeCmd.PersistentFlags().StringSlice("slsa", []string{}, "two slsa to analyze")
// analyzeCmd.PersistentFlags().Bool("uri", false, "input is a URI")
// analyzeCmd.PersistentFlags().Bool("purl", false, "input is a pURL")
// analyzeCmd.PersistentFlags().Bool("id", false, "input is an Id")
// analyzeCmd.PersistentFlags().Bool("metadata", false, "Compare SBOM metadata")
// analyzeCmd.PersistentFlags().Bool("incl-soft", false, "Compare Included Softwares")
// analyzeCmd.PersistentFlags().Bool("incl-deps", false, "Compare Included Dependencies")
// analyzeCmd.PersistentFlags().Bool("incl-occur", false, "Compare Included Occurrences")
// analyzeCmd.PersistentFlags().Bool("namespaces", false, "Compare Package Namespaces")
// analyzeCmd.PersistentFlags().Bool("dot", false, "create diff dot file")
// analyzeCmd.PersistentFlags().Bool("all", false, " lists all")
// analyzeCmd.PersistentFlags().Int("maxprint", 20, "max number of items to print")
// analyzeCmd.PersistentFlags().String("test", "", "test file with sbom")

rootCmd.AddCommand(analyzeCmd)

}
88 changes: 53 additions & 35 deletions pkg/analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,28 @@ import (
"github.com/guacsec/guac/pkg/assembler/helpers"
)

type NodeType int
type Action int

const (
Pkg NodeType = iota
DepPkg
)

func (n NodeType) String() string {
return [...]string{"Pkg", "DepPkg"}[n]
}

const (
Difference Action = iota
Intersection
Union
)

func (a Action) String() string {
return [...]string{"Difference", "Intersectino", "Union"}[a]
}

type Node struct {
ID string
Message string
Expand Down Expand Up @@ -210,12 +232,12 @@ func FindPathsFromHasSBOMNode(g graph.Graph[string, *Node]) ([][]string, error)
return paths, nil
}

func HighlightAnalysis(gOne, gTwo graph.Graph[string, *Node], action int) ([][]*Node, [][]*Node, error) {
func HighlightAnalysis(gOne, gTwo graph.Graph[string, *Node], action Action) ([][]*Node, [][]*Node, error) {
pathsOne, errOne := FindPathsFromHasSBOMNode(gOne)
pathsTwo, errTwo := FindPathsFromHasSBOMNode(gTwo)
var analysisOne, analysisTwo [][]*Node

if errOne != nil || errTwo != nil {
return analysisOne, analysisTwo, fmt.Errorf("error getting graph paths errOne-%v, errTwo-%v", errOne.Error(), errTwo.Error())
return [][]*Node{}, [][]*Node{}, fmt.Errorf("error getting graph paths errOne-%v, errTwo-%v", errOne.Error(), errTwo.Error())
}

pathsOneStrings := concatenateLists(pathsOne)
Expand All @@ -224,6 +246,8 @@ func HighlightAnalysis(gOne, gTwo graph.Graph[string, *Node], action int) ([][]*
pathsOneMap := make(map[string][]*Node)
pathsTwoMap := make(map[string][]*Node)

var analysisOne, analysisTwo [][]*Node

for i := range pathsOne {
nodes, err := nodeIDListToNodeList(gOne, pathsOne[i])
if err != nil {
Expand All @@ -242,49 +266,46 @@ func HighlightAnalysis(gOne, gTwo graph.Graph[string, *Node], action int) ([][]*
}

switch action {
//0 is diff
case 0:

case Difference:
for key, val := range pathsOneMap {
_, ok := pathsTwoMap[key]
if !ok {
//missing

analysisOne = append(analysisOne, val)
}
}

for key, val := range pathsTwoMap {
_, ok := pathsOneMap[key]
if !ok {
//missing

analysisTwo = append(analysisTwo, val)
}
}

//do the compare here
case 1:
// 1 is intersect
case Intersection:
for key := range pathsOneMap {
val, ok := pathsTwoMap[key]
if ok {
//common

analysisOne = append(analysisOne, val)
}
}
//do the compare here
case 2:
//2 is union

case Union:

for _, val := range pathsOneMap {
analysisOne = append(analysisOne, val)
}

for key, val := range pathsTwoMap {
_, ok := pathsOneMap[key]
if !ok {
//common
analysisTwo = append(analysisTwo, val)
}
}
//do the compare here

}

return analysisOne, analysisTwo, nil
Expand Down Expand Up @@ -394,14 +415,14 @@ func nodeHasher(value []byte) string {
return hex.EncodeToString(hash[:])
}

func AddGraphNode(g graph.Graph[string, *Node], _ID, color string) {
func AddGraphNode(g graph.Graph[string, *Node], id, color string) {
var err error
if _, err = g.Vertex(_ID); err == nil {
if _, err = g.Vertex(id); err == nil {
return
}

newNode := &Node{
ID: _ID,
ID: id,
Color: color,
Attributes: make(map[string]interface{}),
}
Expand Down Expand Up @@ -629,7 +650,6 @@ func compareNodes(nodeOne, nodeTwo Node, nodeType string) ([]string, error) {
if k >= len(versionSmall) {
diffs = append(diffs, fmt.Sprintf("Version %s not present for name %s in namespace %s,", version1.Version, name1.Name, namespace1.Namespace))
continue

}

version2 := versionSmall[k]
Expand Down Expand Up @@ -869,20 +889,20 @@ func CompareAllPaths(listOne, listTwo [][]*Node) ([]DiffedPath, error) {

var small, big [][]*Node
if len(listOne) > len(listTwo) {
small= listTwo
small = listTwo
big = listOne
} else if len(listTwo) > len(listOne) {
small= listOne
} else if len(listTwo) > len(listOne) {
small = listOne
big = listTwo
} else {
small= listTwo
small = listTwo
big = listOne
}

var results []DiffedPath
used := make(map[int]bool)
for _, pathOne := range small {

for _, pathOne := range small {

var diff DiffedPath
diff.PathOne = pathOne
Expand All @@ -891,16 +911,15 @@ func CompareAllPaths(listOne, listTwo [][]*Node) ([]DiffedPath, error) {

for i, pathTwo := range big {
_, ok := used[i]
if ok{
if ok {
continue
}

diffs, diffNum, err := CompareTwoPaths(pathOne, pathTwo)

if err != nil {
return results, fmt.Errorf(err.Error())
}


if diffNum < min {
diff.PathTwo = pathTwo
Expand All @@ -914,20 +933,19 @@ func CompareAllPaths(listOne, listTwo [][]*Node) ([]DiffedPath, error) {
}

for i, val := range big {
_, ok := used[i]
_, ok := used[i]
if !ok {
results = append(results, DiffedPath{PathOne: val, })
results = append(results, DiffedPath{PathOne: val})
}
}


return results, nil
}

func GetNodeString(option int, node interface{}) (string, error) {
func GetNodeString(option NodeType, node interface{}) (string, error) {
switch option {

case 1:
case Pkg:
pkg, ok := node.(model.AllIsDependencyTreePackage)
if !ok {
return "", fmt.Errorf("could not case node to tree Pkg")
Expand Down Expand Up @@ -960,7 +978,7 @@ func GetNodeString(option int, node interface{}) (string, error) {
message += "\n"
}
return message, nil
case 2:
case DepPkg:
depPkg, ok := node.(model.AllIsDependencyTreeDependencyPackage)
if !ok {
return "", fmt.Errorf("could not case node to tree depPkg")
Expand Down

0 comments on commit f4b5590

Please sign in to comment.