Skip to content

Commit

Permalink
fix docker scan
Browse files Browse the repository at this point in the history
  • Loading branch information
attiasas committed Jan 16, 2024
1 parent 7a06173 commit a78da30
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 68 deletions.
4 changes: 1 addition & 3 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ import (
)

func GetJfrogCliSecurityApp() components.App {
app := components.CreateApp(
app := components.CreateEmbeddedApp(
"security",
"v1.0.0",
"Jfrog Security CLI embedded plugin",
GetAuditAndScansCommands(),
)
app.Subcommands = append(app.Subcommands, components.Namespace{
Expand Down
53 changes: 28 additions & 25 deletions cli/docs/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ const (
AuditPipenv = "audit-pipenv"
)

const (
Mvn = "mvn"
Gradle = "gradle"
Npm = "npm"
Yarn = "yarn"
Nuget = "nuget"
Go = "go"
Pip = "pip"
Pipenv = "pipenv"
Poetry = "poetry"
)

const (
// Base flags keys
ServerId = "server-id"
Expand All @@ -54,18 +66,6 @@ const (
UseWrapper = "use-wrapper"
)

const (
Mvn = "mvn"
Gradle = "gradle"
Npm = "npm"
Yarn = "yarn"
Nuget = "nuget"
Go = "go"
Pip = "pip"
Pipenv = "pipenv"
Poetry = "poetry"
)

const (
// Unique offline-update flags keys
LicenseId = "license-id"
Expand All @@ -81,7 +81,7 @@ const (
scanRecursive = scanPrefix + Recursive
scanRegexp = scanPrefix + RegexpFlag
scanAnt = scanPrefix + AntFlag
XrOutput = "format"
OutputFormat = "format"
BypassArchiveLimits = "bypass-archive-limits"
Watches = "watches"
RepoPath = "repo-path"
Expand Down Expand Up @@ -114,36 +114,39 @@ var commandFlags = map[string][]string{
OfflineUpdate: {LicenseId, From, To, Version, Target, Stream, Periodic},
XrScan: {
url, user, password, accessToken, ServerId, SpecFlag, Threads, scanRecursive, scanRegexp, scanAnt,
Project, Watches, RepoPath, Licenses, XrOutput, Fail, ExtendedTable, BypassArchiveLimits, MinSeverity, FixableOnly,
Project, Watches, RepoPath, Licenses, OutputFormat, Fail, ExtendedTable, BypassArchiveLimits, MinSeverity, FixableOnly,
},
BuildScan: {
url, user, password, accessToken, ServerId, Project, Vuln, XrOutput, Fail, ExtendedTable, Rescan,
url, user, password, accessToken, ServerId, Project, Vuln, OutputFormat, Fail, ExtendedTable, Rescan,
},
DockerScan: {
ServerId, Project, Watches, RepoPath, Licenses, OutputFormat, Fail, ExtendedTable, BypassArchiveLimits, MinSeverity, FixableOnly,
},
Audit: {
url, user, password, accessToken, ServerId, InsecureTls, Project, Watches, RepoPath, Licenses, XrOutput, ExcludeTestDeps,
url, user, password, accessToken, ServerId, InsecureTls, Project, Watches, RepoPath, Licenses, OutputFormat, ExcludeTestDeps,
useWrapperAudit, DepType, RequirementsFile, Fail, ExtendedTable, WorkingDirs, ExclusionsAudit, Mvn, Gradle, Npm, Yarn, Go, Nuget, Pip, Pipenv, Poetry, MinSeverity, FixableOnly, ThirdPartyContextualAnalysis,
},
CurationAudit: {
CurationOutput, WorkingDirs, CurationThreads,
},
// TODO: Deprecated commands (remove at next CLI major version)
AuditMvn: {
url, user, password, accessToken, ServerId, InsecureTls, Project, ExclusionsAudit, Watches, RepoPath, Licenses, XrOutput, Fail, ExtendedTable, useWrapperAudit,
url, user, password, accessToken, ServerId, InsecureTls, Project, ExclusionsAudit, Watches, RepoPath, Licenses, OutputFormat, Fail, ExtendedTable, useWrapperAudit,
},
AuditGradle: {
url, user, password, accessToken, ServerId, ExcludeTestDeps, ExclusionsAudit, useWrapperAudit, Project, Watches, RepoPath, Licenses, XrOutput, Fail, ExtendedTable,
url, user, password, accessToken, ServerId, ExcludeTestDeps, ExclusionsAudit, useWrapperAudit, Project, Watches, RepoPath, Licenses, OutputFormat, Fail, ExtendedTable,
},
AuditNpm: {
url, user, password, accessToken, ServerId, DepType, Project, ExclusionsAudit, Watches, RepoPath, Licenses, XrOutput, Fail, ExtendedTable,
url, user, password, accessToken, ServerId, DepType, Project, ExclusionsAudit, Watches, RepoPath, Licenses, OutputFormat, Fail, ExtendedTable,
},
AuditGo: {
url, user, password, accessToken, ServerId, Project, ExclusionsAudit, Watches, RepoPath, Licenses, XrOutput, Fail, ExtendedTable,
url, user, password, accessToken, ServerId, Project, ExclusionsAudit, Watches, RepoPath, Licenses, OutputFormat, Fail, ExtendedTable,
},
AuditPip: {
url, user, password, accessToken, ServerId, RequirementsFile, Project, ExclusionsAudit, Watches, RepoPath, Licenses, XrOutput, Fail, ExtendedTable,
url, user, password, accessToken, ServerId, RequirementsFile, Project, ExclusionsAudit, Watches, RepoPath, Licenses, OutputFormat, Fail, ExtendedTable,
},
AuditPipenv: {
url, user, password, accessToken, ServerId, Project, ExclusionsAudit, Watches, RepoPath, Licenses, XrOutput, ExtendedTable,
url, user, password, accessToken, ServerId, Project, ExclusionsAudit, Watches, RepoPath, Licenses, OutputFormat, ExtendedTable,
},
}

Expand Down Expand Up @@ -173,8 +176,8 @@ var flagsMap = map[string]components.Flag{
Watches: components.NewStringFlag(Watches, "A comma-separated list of Xray watches, to determine Xray's violations creation."),
RepoPath: components.NewStringFlag(RepoPath, "Target repo path, to enable Xray to determine watches accordingly."),
Licenses: components.NewBoolFlag(Licenses, "Set to true if you'd like to receive licenses from Xray scanning."),
XrOutput: components.NewStringFlag(
XrOutput,
OutputFormat: components.NewStringFlag(
OutputFormat,
"Defines the output format of the command. Acceptable values are: table, json, simple-json and sarif. Note: the json format doesn't include information about scans that are included as part of the Advanced Security package.",
components.WithStrDefaultValue("table"),
),
Expand Down Expand Up @@ -215,7 +218,7 @@ var flagsMap = map[string]components.Flag{
),
RequirementsFile: components.NewStringFlag(RequirementsFile, "[Pip] Defines pip requirements file name. For example: 'requirements.txt'."),
CurationThreads: components.NewStringFlag(Threads, "Number of working threads.", components.WithIntDefaultValue(curation.TotalConcurrentRequests)),
CurationOutput: components.NewStringFlag(XrOutput, "Defines the output format of the command. Acceptable values are: table, json.", components.WithStrDefaultValue("table")),
CurationOutput: components.NewStringFlag(OutputFormat, "Defines the output format of the command. Acceptable values are: table, json.", components.WithStrDefaultValue("table")),
}

func GetCommandFlags(cmdKey string) []components.Flag {
Expand Down
18 changes: 18 additions & 0 deletions cli/docs/scan/dockerscan/help.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package dockerscan

import "github.com/jfrog/jfrog-cli-core/v2/plugins/components"

var Usage = []string{"docker scan <image tag>"}

func GetDescription() string {
return "Scan local docker image using the docker client and Xray."
}

func GetArguments() []components.Argument {
return []components.Argument{
{
Name: "image tag",
Description: "The docker image tag to scan.",
},
}
}
37 changes: 27 additions & 10 deletions cli/scancommands.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
auditDocs "github.com/jfrog/jfrog-cli-security/cli/docs/scan/audit"
buildScanDocs "github.com/jfrog/jfrog-cli-security/cli/docs/scan/buildscan"
curationDocs "github.com/jfrog/jfrog-cli-security/cli/docs/scan/curation"
dockerScanDocs "github.com/jfrog/jfrog-cli-security/cli/docs/scan/dockerscan"
scanDocs "github.com/jfrog/jfrog-cli-security/cli/docs/scan/scan"

"github.com/jfrog/jfrog-cli-security/commands/audit"
Expand All @@ -29,10 +30,10 @@ import (
"github.com/jfrog/jfrog-cli-security/utils"
)

// TODO: replace dependencies at commands/utils from jfrog-cli-core/v2 to jfrog-cli-security

const auditScanCategory = "Audit & Scan"

const dockerScanCmdHiddenName = "dockerscan"

func GetAuditAndScansCommands() []components.Command {
return []components.Command{
{
Expand All @@ -53,6 +54,19 @@ func GetAuditAndScansCommands() []components.Command {
Category: auditScanCategory,
Action: BuildScan,
},
{
// this command is hidden and have no logic, it will be run to provide 'help' as a part of the buildtools CLI for 'docker' commands. ('jf docker scan')
// CLI buildtools will run the command if requested: https://github.com/jfrog/jfrog-cli/blob/v2/buildtools/cli.go
Name: dockerScanCmdHiddenName,
Flags: flags.GetCommandFlags(flags.DockerScan),
Description: dockerScanDocs.GetDescription(),
Arguments: dockerScanDocs.GetArguments(),
UsageOptions: &components.UsageOptions{
Usage: dockerScanDocs.Usage,
ReplaceAutoGeneratedUsage: true,
},
Hidden: true,
},
{
Name: "audit",
Aliases: []string{"aud"},
Expand Down Expand Up @@ -163,7 +177,7 @@ func ScanCmd(c *components.Context) error {
if err != nil {
return err
}
format, err := outputFormat.GetOutputFormat(c.GetStringFlagValue(flags.XrOutput))
format, err := outputFormat.GetOutputFormat(c.GetStringFlagValue(flags.OutputFormat))
if err != nil {
return err
}
Expand Down Expand Up @@ -228,7 +242,6 @@ func addTrailingSlashToRepoPathIfNeeded(c *components.Context) string {
return repoPath
}

// TODO: Exclusions and include-dirs are not flags of the scan command at the CLI right now but there is logic there, but of the spec use? Ask to make sure it's ok.
func createDefaultScanSpec(c *components.Context, defaultTarget string) *spec.SpecFiles {
return spec.NewBuilder().
Pattern(c.Arguments[0]).
Expand Down Expand Up @@ -272,7 +285,7 @@ func BuildScan(c *components.Context) error {
if err != nil {
return err
}
format, err := outputFormat.GetOutputFormat(c.GetStringFlagValue(flags.XrOutput))
format, err := outputFormat.GetOutputFormat(c.GetStringFlagValue(flags.OutputFormat))
if err != nil {
return err
}
Expand Down Expand Up @@ -325,7 +338,7 @@ func createAuditCmd(c *components.Context) (*audit.AuditCommand, error) {
if err != nil {
return nil, err
}
format, err := outputFormat.GetOutputFormat(c.GetStringFlagValue(flags.XrOutput))
format, err := outputFormat.GetOutputFormat(c.GetStringFlagValue(flags.OutputFormat))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -400,7 +413,7 @@ func CurationCmd(c *components.Context) error {
if err != nil {
return err
}
format, err := curation.GetCurationOutputFormat(c.GetStringFlagValue(flags.XrOutput))
format, err := curation.GetCurationOutputFormat(c.GetStringFlagValue(flags.OutputFormat))
if err != nil {
return err
}
Expand All @@ -415,12 +428,16 @@ func CurationCmd(c *components.Context) error {
}

func DockerScan(c *components.Context, image string) error {
if show, err := cliutils.ShowGenericCmdHelpIfNeeded(c.Arguments, func() error { return c.PrintCommandHelp("dockerscanhelp") }); show || err != nil {
// Since this command is not registered normally, we need to handle printing 'help' here by ourselves.
c.CommandName = dockerScanCmdHiddenName
printHelp := pluginsCommon.GetPrintCurrentCmdHelp(c)
if show, err := cliutils.ShowGenericCmdHelpIfNeeded(c.Arguments, printHelp); show || err != nil {
return err
}
if image == "" {
return c.PrintCommandHelp("dockerscanhelp")
return printHelp()
}
// Run the command
serverDetails, err := createServerDetailsWithConfigOffer(c)
if err != nil {
return err
Expand All @@ -430,7 +447,7 @@ func DockerScan(c *components.Context, image string) error {
return err
}
containerScanCommand := scan.NewDockerScanCommand()
format, err := outputFormat.GetOutputFormat(c.GetStringFlagValue(flags.XrOutput))
format, err := outputFormat.GetOutputFormat(c.GetStringFlagValue(flags.OutputFormat))
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,4 @@ require (
gopkg.in/warnings.v0 v0.1.2 // indirect
)

replace github.com/jfrog/jfrog-cli-core/v2 => github.com/attiasas/jfrog-cli-core/v2 v2.0.0-20240111145839-b856a91ecdc6
replace github.com/jfrog/jfrog-cli-core/v2 => github.com/attiasas/jfrog-cli-core/v2 v2.0.0-20240116073017-ba718fa44435
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/attiasas/jfrog-cli-core/v2 v2.0.0-20240111145839-b856a91ecdc6 h1:oK813X9R1dIM30x4XnIN9/1UfYQurCdTCwnkZYHSKl4=
github.com/attiasas/jfrog-cli-core/v2 v2.0.0-20240111145839-b856a91ecdc6/go.mod h1:MBdk6VvRW27IojGy9UJ2F2pAucVuB6ecS15DQ5rHAH8=
github.com/attiasas/jfrog-cli-core/v2 v2.0.0-20240116073017-ba718fa44435 h1:DuGbu21nmWP7isSPRbwQ1jwAzRnW3QPT4h7FO4UNK8s=
github.com/attiasas/jfrog-cli-core/v2 v2.0.0-20240116073017-ba718fa44435/go.mod h1:MBdk6VvRW27IojGy9UJ2F2pAucVuB6ecS15DQ5rHAH8=
github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M=
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
Expand Down
Loading

0 comments on commit a78da30

Please sign in to comment.