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

feat(engine): add kics analyze command #6582

Merged
merged 10 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ kics.config

# Results
results.*
platforms.json
gl-sast-results.json
sonarqube-results.json
cyclonedx-results.xml
Expand Down
6 changes: 6 additions & 0 deletions e2e/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,16 @@ func prepareTemplates() testcases.TestTemplates {
remediateHelp = []string{}
}

var analyzeHelp, errAH = utils.PrepareExpected("analyze_help", "fixtures/assets")
if errAH != nil {
analyzeHelp = []string{}
}

return testcases.TestTemplates{
Help: strings.Join(help, "\n"),
ScanHelp: strings.Join(scanHelp, "\n"),
RemediateHelp: strings.Join(remediateHelp, "\n"),
AnalyzeHelp: strings.Join(analyzeHelp, "\n"),
}
}

Expand Down
1 change: 1 addition & 0 deletions e2e/fixtures/E2E_CLI_066_ANALYZE_RESULTS.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Types":["ansible","openapi"],"Exc":[],"ExpectedLOC":1233}
18 changes: 18 additions & 0 deletions e2e/fixtures/assets/analyze_help
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Usage:
kics remediate [flags]

Flags:
-h, --help help for analyze
--analyze-path strings paths or directories to scan
example: "./somepath,somefile.txt"
--analyze-results string points to the JSON results file of analyzer (default "platforms.json")

Global Flags:
--ci display only log messages to CLI output (mutually exclusive with silent)
-f, --log-format string determines log format (pretty,json) (default "pretty")
--log-level string determines log level (TRACE,DEBUG,INFO,WARN,ERROR,FATAL) (default "INFO")
--log-path string path to generate log file (info.log)
--no-color disable CLI color output
--profiling string enables performance profiler that prints resource consumption metrics in the logs during the execution (CPU, MEM)
-s, --silent silence stdout messages (mutually exclusive with verbose and ci)
-v, --verbose write logs to stdout too (mutually exclusive with silent)
1 change: 1 addition & 0 deletions e2e/fixtures/assets/help
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Usage:
kics [command]

Available Commands:
analyze Determines the detected platforms of a certain project
generate-id Generates uuid for query
help Help about any command
list-platforms List supported platforms
Expand Down
26 changes: 26 additions & 0 deletions e2e/testcases/e2e-cli-066_analyze_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Package testcases provides end-to-end (E2E) testing functionality for the application.
package testcases

// E2E-CLI-066 - KICS analyze
// should finish successfully and return exit code 0
func init() { //nolint
testSample := TestCase{
Name: "should perform a valid analyze [E2E-CLI-066]",
Args: args{
Args: []cmdArgs{
[]string{"analyze",
"--analyze-path", "/path/e2e/fixtures/samples/swagger",
"--analyze-results", "/path/e2e/output/E2E_CLI_066_ANALYZE_RESULTS.json"},
},
UseMock: []bool{true, true},
ExpectedResult: []ResultsValidation{
{
ResultsFile: "E2E_CLI_066_ANALYZE_RESULTS",
ResultsFormats: []string{"json"},
},
},
},
WantStatus: []int{126},
}
Tests = append(Tests, testSample)
}
1 change: 1 addition & 0 deletions e2e/testcases/general.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type TestTemplates struct {
Help string
ScanHelp string
RemediateHelp string
AnalyzeHelp string
}

type cmdArgs []string
Expand Down
126 changes: 126 additions & 0 deletions internal/console/analyze.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package console

import (
_ "embed" // Embed kics CLI img and analyze-flags
"encoding/json"
"os"

"github.com/Checkmarx/kics/internal/console/flags"
sentryReport "github.com/Checkmarx/kics/internal/sentry"
"github.com/Checkmarx/kics/pkg/analyzer"
"github.com/Checkmarx/kics/pkg/engine/source"
"github.com/Checkmarx/kics/pkg/model"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

var (
//go:embed assets/analyze-flags.json
analyzeFlagsListContent string
)

// NewAnalyzeCmd creates a new instance of the analyze Command
func NewAnalyzeCmd() *cobra.Command {
return &cobra.Command{
Use: "analyze",
Short: "Determines the detected platforms of a certain project",
RunE: func(cmd *cobra.Command, args []string) error {
return analyze()
},
}
}

func initAnalyzeCmd(analyzeCmd *cobra.Command) error {
if err := flags.InitJSONFlags(
analyzeCmd,
analyzeFlagsListContent,
false,
source.ListSupportedPlatforms(),
source.ListSupportedCloudProviders()); err != nil {
return err
}

if err := analyzeCmd.MarkFlagRequired(flags.AnalyzePath); err != nil {
sentryReport.ReportSentry(&sentryReport.Report{
Message: "Failed to add command required flags",
Err: err,
Location: "func initAnalyzeCmd()",
}, true)
log.Err(err).Msg("Failed to add command required flags")
}
return nil
}

func analyze() error {
// save the analyze parameters into the AnalyzeParameters struct
analyzeParams := getAnalyzeParameters()

return executeAnalyze(analyzeParams)
}

func getAnalyzeParameters() *analyzer.Parameters {
analyzeParams := analyzer.Parameters{
Path: flags.GetMultiStrFlag(flags.AnalyzePath),
Results: flags.GetStrFlag(flags.AnalyzeResults),
}

return &analyzeParams
}

func executeAnalyze(analyzeParams *analyzer.Parameters) error {
log.Debug().Msg("console.scan()")

for _, warn := range warnings {
log.Warn().Msgf(warn)
}

console := newConsole()

console.preScan()

analyzerStruct := &analyzer.Analyzer{
Paths: analyzeParams.Path,
Types: []string{""},
ExcludeTypes: []string{""},
Exc: []string{""},
ExcludeGitIgnore: false,
GitIgnoreFileName: "",
}

analyzedPaths, err := analyzer.Analyze(analyzerStruct)

if err != nil {
log.Err(err)
return err
}

err = writeToFile(analyzeParams.Results, analyzedPaths)

if err != nil {
log.Err(err)
return err
}

return nil
}

func writeToFile(resultsPath string, analyzerResults model.AnalyzedPaths) error {
f, err := os.Create(resultsPath)
Dismissed Show dismissed Hide dismissed
if err != nil {
return err
}

defer f.Close()

content, err := json.Marshal(analyzerResults)
if err != nil {
return err
}

_, err = f.Write(content)
if err != nil {
return err
}

return nil
}
14 changes: 14 additions & 0 deletions internal/console/assets/analyze-flags.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"analyze-path": {
"flagType": "multiStr",
"shorthandFlag": "",
"defaultValue": null,
"usage": "paths or directories to scan\nexample: \"./somepath,somefile.txt\""
},
"analyze-results": {
"flagType": "str",
"shorthandFlag": "",
"defaultValue": "platforms.json",
"usage": "points to the JSON results file of analyzer"
}
}
7 changes: 7 additions & 0 deletions internal/console/flags/analyze_flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package flags

// Flags constants for analyze
const (
AnalyzeResults = "analyze-results"
AnalyzePath = "analyze-path"
)
6 changes: 6 additions & 0 deletions internal/console/kics.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ func NewKICSCmd() *cobra.Command {
func initialize(rootCmd *cobra.Command) error {
scanCmd := NewScanCmd()
remediateCmd := NewRemediateCmd()
analyzeCmd := NewAnalyzeCmd()
rootCmd.AddCommand(NewVersionCmd())
rootCmd.AddCommand(NewGenerateIDCmd())
rootCmd.AddCommand(scanCmd)
rootCmd.AddCommand(NewListPlatformsCmd())
rootCmd.AddCommand(remediateCmd)
rootCmd.AddCommand(analyzeCmd)
rootCmd.CompletionOptions.DisableDefaultCmd = true

if err := flags.InitJSONFlags(
Expand All @@ -67,6 +69,10 @@ func initialize(rootCmd *cobra.Command) error {
return err
}

if err := initAnalyzeCmd(analyzeCmd); err != nil {
return err
}

return initScanCmd(scanCmd)
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ const (
knative = "knative"
)

type Parameters struct {
Results string
Path []string
}

// regexSlice is a struct to contain a slice of regex
type regexSlice struct {
regex []*regexp.Regexp
Expand Down
Loading