-
Notifications
You must be signed in to change notification settings - Fork 176
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
Adding Analyze command to guacone #1809
base: main
Are you sure you want to change the base?
Conversation
@pxp928 ready for review. |
Cool, @arorasoham9 can you add some screenshots to what the output will look like for the CLI? |
pkg/analyzer/analyze.go
Outdated
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package guacanalyze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one major task would be to add unit tests to this package. Some things like the graph, getting data from graphQL can be abstracted away but do you have some tests you can add here to test the functionality?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have any at the moment. I can write a few. Could they come in a future PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added unit tests as requested.
Added some screenshots. The Prettify function errored out at many instances so I improvised to print the same details that function does but taken from the graph DS itself, not graphQL. |
pkg/analyzer/analyze.go
Outdated
node *Node | ||
) | ||
if node, err = g.Vertex(ID); err != nil { | ||
fmt.Println("Error setting node attribute", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to return this as an error.
pkg/analyzer/analyze.go
Outdated
) | ||
if node, err = g.Vertex(ID); err != nil { | ||
fmt.Println("Error setting node attribute", err) | ||
os.Exit(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't use os.Exit(1)
should return error
pkg/analyzer/analyze.go
Outdated
|
||
func GetNodeAttribute(g graph.Graph[string, *Node],ID, key string) interface{} { | ||
var ( | ||
err error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to instantiate this here, can just it on line 72?
pkg/analyzer/analyze.go
Outdated
node.Attributes[key] = value | ||
} | ||
|
||
func GetNodeAttribute(g graph.Graph[string, *Node],ID, key string) interface{} { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this returning an interface{}
pkg/analyzer/analyze.go
Outdated
foundHasSBOMPkg, err = model.HasSBOMs(ctx, gqlclient, model.HasSBOMSpec{Subject: &model.PackageOrArtifactSpec{Package: &model.PkgSpec{Id: &pkgResponse.Packages[0].Namespaces[0].Names[0].Versions[0].Id}}, | ||
}) | ||
if err != nil { | ||
fmt.Printf("(purl)failed getting hasSBOM with error :%v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dont use fmt.Printf
, you should return an error via fmt.Errorf
pkg/analyzer/analyze.go
Outdated
func verifyAnalyzeFlags(slsas, sboms []string, errSlsa, errSbom error, uri, purl, id bool) { | ||
|
||
if (errSlsa != nil && errSbom != nil) || (len(slsas) ==0 && len(sboms) == 0 ){ | ||
fmt.Println("Must specify slsa or sboms ") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return a proper error and dont use os.Exit
pkg/analyzer/analyze.go
Outdated
namespaceTwo, okTwo := GetNodeAttribute(analysisGraph,diffList.MissingAddedRemovedLinks[i][1], "Namespace[0]").(string) | ||
|
||
if !okOne || !okTwo { | ||
fmt.Println("Error getting node namespace attribute") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clean up and pass out proper error
pkg/analyzer/analyze.go
Outdated
table.SetAlignment(tablewriter.ALIGN_LEFT) | ||
table.Render() | ||
if (!all && max > maxprint){ | ||
fmt.Println("Run with --all to see full list") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should user logger here: https://github.com/guacsec/guac/blob/main/pkg/handler/processor/process/process.go#L117
It should be able to be pulled from the context:
logger := logging.FromContext(ctx)
pkg/analyzer/analyze.go
Outdated
} | ||
|
||
func HasSBOMToGraph(cmd *cobra.Command, ctx context.Context, gqlclient graphql.Client) ( []graph.Graph[string, *Node]){ | ||
slsas, errSlsa := cmd.Flags().GetStringSlice("slsa") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass in options or something similar and not the actual cmd
. See: https://github.com/guacsec/guac/blob/main/cmd/guacone/cmd/s3.go#L80-L93
pkg/analyzer/analyze.go
Outdated
if uri { | ||
hasSBOMResponseOne, err = FindHasSBOMBy(model.HasSBOMSpec{} ,sboms[0],"", "", ctx, gqlclient) | ||
if err != nil { | ||
fmt.Println("(uri)failed to lookup sbom:", sboms[0], err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix error
pkg/analyzer/analyze_test.go
Outdated
@@ -0,0 +1,66 @@ | |||
package guacanalyze_test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing header
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly code organization and naming comments.
cmd/guacone/cmd/analyze.go
Outdated
"github.com/guacsec/guac/pkg/logging" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
analysis "github.com/guacsec/guac/pkg/analyzer" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason for the import rename here?
cmd/guacone/cmd/analyze.go
Outdated
if diff && intersect && union || diff && intersect || diff && union || intersect && union { | ||
fmt.Println("Must specify only one of --diff, --intersect, --union") | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a positional argument if required, not a flag/option.
cmd/guacone/cmd/analyze.go
Outdated
} | ||
|
||
//create graphs | ||
graphs := analysis.HasSBOMToGraph(cmd, ctx, gqlclient) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't pass cmd to a package under pkg/
. Those shouldn't have a dependency on cli commands or cobra. Explicitly pass the parameters this needs.
cmd/guacone/cmd/analyze.go
Outdated
|
||
func init() { | ||
|
||
rootCmd.PersistentFlags().Bool("intersect", false, "compute intesection of given sboms") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't add flags to rootCmd, this will show up on all guacone
cmds if so. Use this analyzeCmd
you are creating.
Also, cli options are normally under pkg/cli/store.go
but this command has so many it might make sense to just leave them here.
cmd/guacone/cmd/analyze.go
Outdated
rootCmd.PersistentFlags().Bool("purl", false, "input is a pURL") | ||
rootCmd.PersistentFlags().Bool("id", false, "input is an Id") | ||
rootCmd.PersistentFlags().Bool("metadata", false, "Compare SBOM metadata") | ||
rootCmd.PersistentFlags().Bool("inclSoft", false, "Compare Included Softwares") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change to incl-soft
and similar for others. All cli options use hyphen-case.
cmd/guacone/cmd/analyze.go
Outdated
rootCmd.PersistentFlags().Int("maxprint", PRINT_MAX, "max number of similar sboms to print") | ||
rootCmd.AddCommand(analyzeCmd) | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a newline to the end of the file
pkg/analyzer/analyze.go
Outdated
) | ||
if node, err = g.Vertex(ID); err != nil { | ||
fmt.Println("Error setting node attribute", err) | ||
os.Exit(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't have any os.Exit in a package under pkg/
, assume this is a library that can be called from anywhere. Propagate errors back to the caller.
pkg/analyzer/analyze.go
Outdated
return foundHasSBOMPkg, nil | ||
} | ||
|
||
func verifyAnalyzeFlags(slsas, sboms []string, errSlsa, errSbom error, uri, purl, id bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All this should be under the file in cmd/
, shouldn't have any flag validation here in pkg/
.
pkg/analyzer/analyze.go
Outdated
//print to stdout | ||
printHighlightedAnalysis(dot, diffList, all, maxprint, action, analysisGraph ) | ||
} | ||
func max(nums []int) int { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add an empty line between functions.
pkg/analyzer/analyze.go
Outdated
//Create dot file | ||
createGraphDotFile(dot, analysisGraph) | ||
//print to stdout | ||
printHighlightedAnalysis(dot, diffList, all, maxprint, action, analysisGraph ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anything under pkg/
should not print anything to stdout. Any logic should result in a datastructure that returns back to cmd/
and is then printed. This helps for testability. Looks like much of this may need to be moved back to cmd/
@arorasoham9 did the |
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
…th the comparing path, not sure which to use Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Signed-off-by: Soham Arora <arorasoham9@gmail.com>
Hey @arorasoham9 , would you be able to chat at bit more amount helping to turn the corner to complete the PR. |
Signed-off-by: arorasoham9 <68672198+arorasoham9@users.noreply.github.com>
Signed-off-by: arorasoham9 <68672198+arorasoham9@users.noreply.github.com>
Description of the PR
Analyze command for guacone
Comparing SBOMs with only patch version differences
guacone analyze diff --uri --sboms=https://anchore.com/syft/image/k8s.gcr.io/kube-apiserver-v1.24.1-583a02ce-8f7e-4794-91af-35f27ffeb73d,https://anchore.com/syft/image/k8s.gcr.io/kube-apiserver-v1.24.2-ee7e0a81-87de-4761-9689-4f7162d81e44
The diff is a 4 step process:
Each step has tests to ensure that it is stable. Meaning, if the steps are repeated for the same Input SBOM, the results are the same. The JSON you see are the test SBOMS I use to carry out the tests for each step of the diff. These JSON files are marshalled HasSBOM nodes for SBOMs I ingested into GUAC, pulled using the Node function.
PR Checklist
-s
flag togit commit
.make generate
has been runmake generate
has been runcollectsub
protobuf has been changed,make proto
has been run