Skip to content

Commit

Permalink
Added centralized config resolution and utilization for Scan-PR flow (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
eranturgeman authored Sep 5, 2024
1 parent c1a62b7 commit bce4aee
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 14 deletions.
7 changes: 3 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ require (
github.com/jfrog/build-info-go v1.9.35
github.com/jfrog/froggit-go v1.16.1
github.com/jfrog/gofrog v1.7.5
github.com/jfrog/jfrog-cli-core/v2 v2.55.6
github.com/jfrog/jfrog-cli-security v1.7.2
github.com/jfrog/jfrog-cli-core/v2 v2.55.7
github.com/jfrog/jfrog-cli-security v1.8.0
github.com/jfrog/jfrog-client-go v1.46.1
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
github.com/owenrumney/go-sarif/v2 v2.3.1
Expand Down Expand Up @@ -119,8 +119,7 @@ require (
gopkg.in/warnings.v0 v0.1.2 // indirect
)

// attiasas:dockerscan_sarif_imp
replace github.com/jfrog/jfrog-cli-security => github.com/attiasas/jfrog-cli-security v0.0.0-20240904115644-bb15ff25795e
// replace github.com/jfrog/jfrog-cli-security => github.com/jfrog/jfrog-cli-security dev

// replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev

Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -633,8 +633,6 @@ github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2
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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/attiasas/jfrog-cli-security v0.0.0-20240904115644-bb15ff25795e h1:6gfhwBjKr/MghP7ZwPFR1pvqg7mb//PdE5mCMk3vu/M=
github.com/attiasas/jfrog-cli-security v0.0.0-20240904115644-bb15ff25795e/go.mod h1:4eztJ+gBb7Xtq/TtnOvIodBOMZutPIAZOuLxqHWXrOo=
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M=
Expand Down Expand Up @@ -901,8 +899,10 @@ github.com/jfrog/gofrog v1.7.5 h1:dFgtEDefJdlq9cqTRoe09RLxS5Bxbe1Ev5+E6SmZHcg=
github.com/jfrog/gofrog v1.7.5/go.mod h1:jyGiCgiqSSR7k86hcUSu67XVvmvkkgWTmPsH25wI298=
github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYLipdsOFMY=
github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w=
github.com/jfrog/jfrog-cli-core/v2 v2.55.6 h1:3tQuEdYgS2q7fkrrSG66OnO0S998FXGaY9BVsxSLst4=
github.com/jfrog/jfrog-cli-core/v2 v2.55.6/go.mod h1:DPO5BfWAeOByahFMMy+PcjmbPlcyoRy7Bf2C5sGKVi0=
github.com/jfrog/jfrog-cli-core/v2 v2.55.7 h1:V4dO2FMNIH49lov3dMj3jYRg8KBTG7hyhHI8ftYByf8=
github.com/jfrog/jfrog-cli-core/v2 v2.55.7/go.mod h1:DPO5BfWAeOByahFMMy+PcjmbPlcyoRy7Bf2C5sGKVi0=
github.com/jfrog/jfrog-cli-security v1.8.0 h1:jp/AVaQcItUNXRCud5PMyl8VVjPuzfrNHJWQvWAMnms=
github.com/jfrog/jfrog-cli-security v1.8.0/go.mod h1:DjufYZpsTwILOFJlx7tR/y63oLBRmtPtFIz1WgiP/X4=
github.com/jfrog/jfrog-client-go v1.46.1 h1:ExqOF8ClOG9LO3vbm6jTIwQHHhprbu8lxB2RrM6mMI0=
github.com/jfrog/jfrog-client-go v1.46.1/go.mod h1:UCu2JNBfMp9rypEmCL84DCooG79xWIHVadZQR3Ab+BQ=
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
Expand Down
3 changes: 2 additions & 1 deletion scanpullrequest/scanpullrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ func auditPullRequest(repoConfig *utils.Repository, client vcsclient.VcsClient,
scanDetails := utils.NewScanDetails(client, &repoConfig.Server, &repoConfig.Git).
SetXrayGraphScanParams(repoConfig.Watches, repoConfig.JFrogProjectKey, len(repoConfig.AllowedLicenses) > 0).
SetFixableOnly(repoConfig.FixableOnly).
SetFailOnInstallationErrors(*repoConfig.FailOnSecurityIssues)
SetFailOnInstallationErrors(*repoConfig.FailOnSecurityIssues).
SetConfigProfile(repoConfig.ConfigProfile)
if scanDetails, err = scanDetails.SetMinSeverity(repoConfig.MinSeverity); err != nil {
return
}
Expand Down
8 changes: 4 additions & 4 deletions scanpullrequest/scanpullrequest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,15 @@ func TestCreateVulnerabilitiesRowsCaseNoPrevViolations(t *testing.T) {
IssueId: "XRAY-1",
Summary: "summary-1",
ImpactedDependencyDetails: formats.ImpactedDependencyDetails{
SeverityDetails: formats.SeverityDetails{Severity: "High"},
SeverityDetails: formats.SeverityDetails{Severity: "High", SeverityNumValue: 15},
ImpactedDependencyName: "component-A",
},
},
{
IssueId: "XRAY-2",
Summary: "summary-2",
ImpactedDependencyDetails: formats.ImpactedDependencyDetails{
SeverityDetails: formats.SeverityDetails{Severity: "Low"},
SeverityDetails: formats.SeverityDetails{Severity: "Low", SeverityNumValue: 9},
ImpactedDependencyName: "component-C",
},
},
Expand Down Expand Up @@ -342,7 +342,7 @@ func TestGetNewVulnerabilitiesCaseNoPrevVulnerabilities(t *testing.T) {
Summary: "summary-2",
IssueId: "XRAY-2",
ImpactedDependencyDetails: formats.ImpactedDependencyDetails{
SeverityDetails: formats.SeverityDetails{Severity: "Low"},
SeverityDetails: formats.SeverityDetails{Severity: "Low", SeverityNumValue: 9},
ImpactedDependencyName: "component-B",
},
JfrogResearchInformation: &formats.JfrogResearchInformation{Details: "description-2"},
Expand All @@ -351,7 +351,7 @@ func TestGetNewVulnerabilitiesCaseNoPrevVulnerabilities(t *testing.T) {
Summary: "summary-1",
IssueId: "XRAY-1",
ImpactedDependencyDetails: formats.ImpactedDependencyDetails{
SeverityDetails: formats.SeverityDetails{Severity: "High"},
SeverityDetails: formats.SeverityDetails{Severity: "High", SeverityNumValue: 15},
ImpactedDependencyName: "component-A",
},
JfrogResearchInformation: &formats.JfrogResearchInformation{Details: "description-1"},
Expand Down
49 changes: 49 additions & 0 deletions testdata/configprofile/configProfileExample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"profile_name": "default-profile",
"frogbot_config": {
"email_author": "[email protected]",
"aggregate_fixes": true,
"avoid_previous_pr_comments_deletion": true,
"branch_name_template": "frogbot-${IMPACTED_PACKAGE}-${BRANCH_NAME_HASH}",
"pr_title_template": "[🐸 Frogbot] Upgrade {IMPACTED_PACKAGE} to {FIX_VERSION}",
"pr_comment_title": "Frogbot notes:",
"commit_message_template": "Upgrade {IMPACTED_PACKAGE} to {FIX_VERSION}",
"show_secrets_as_pr_comment": false
},
"modules": [
{
"module_name": "default-module",
"path_from_root": ".",
"releases_repo": "nuget-remote",
"analyzer_manager_version": "1.8.1",
"additional_paths_for_module": ["lib1", "utils/lib2"],
"exclude_paths": ["**/.git/**", "**/*test*/**", "**/*venv*/**", "**/*node_modules*/**", "**/target/**"],
"scan_config": {
"scan_timeout": 600,
"exclude_pattern": "*.md",
"enable_sca_scan": true,
"enable_contextual_analysis_scan": true,
"sast_scanner_config": {
"enable_sast_scan": true
},
"secrets_scanner_config": {
"enable_secrets_scan": true
},
"iac_scanner_config": {
"enable_iac_scan": true
},
"applications_scanner_config": {
"enable_applications_scan": true
},
"services_scanner_config": {
"enable_services_scan": true
}
},
"protected_branches": ["main", "master"],
"include_exclude_mode": 0,
"include_exclude_pattern": "*test*",
"report_analytics": true
}
],
"is_default": true
}
1 change: 1 addition & 0 deletions utils/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const (
jfrogReleasesRepoEnv = "JF_RELEASES_REPO"
JFrogPasswordEnv = "JF_PASSWORD"
JFrogTokenEnv = "JF_ACCESS_TOKEN"
JfrogConfigProfileEnv = "JF_CONFIG_PROFILE"

// Git environment variables
GitProvider = "JF_GIT_PROVIDER"
Expand Down
40 changes: 40 additions & 0 deletions utils/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"errors"
"fmt"
"github.com/jfrog/jfrog-cli-security/utils/xsc"
"github.com/jfrog/jfrog-client-go/xsc/services"
"net/http"
"net/url"
"os"
Expand Down Expand Up @@ -136,6 +138,7 @@ type Scan struct {
AllowedLicenses []string `yaml:"allowedLicenses,omitempty"`
Projects []Project `yaml:"projects,omitempty"`
EmailDetails `yaml:",inline"`
ConfigProfile *services.ConfigProfile
}

type EmailDetails struct {
Expand Down Expand Up @@ -354,6 +357,12 @@ func GetFrogbotDetails(commandName string) (frogbotDetails *FrogbotDetails, err
if err != nil {
return
}

configProfile, err := getConfigProfileIfExistsAndValid(jfrogServer)
if err != nil {
return
}

gitParamsFromEnv, err := extractGitParamsFromEnvs(commandName)
if err != nil {
return
Expand Down Expand Up @@ -381,6 +390,11 @@ func GetFrogbotDetails(commandName string) (frogbotDetails *FrogbotDetails, err
return
}

// We apply the configProfile to all received repositories. This loop must be deleted when we will no longer accept multiple repositories in a single scan
for i := range configAggregator {
configAggregator[i].Scan.ConfigProfile = configProfile
}

frogbotDetails = &FrogbotDetails{Repositories: configAggregator, GitClient: client, ServerDetails: jfrogServer, ReleasesRepo: os.Getenv(jfrogReleasesRepoEnv)}
return
}
Expand Down Expand Up @@ -706,3 +720,29 @@ func readConfigFromTarget(client vcsclient.VcsClient, gitParamsFromEnv *Git) (co
}
return
}

// This function fetches a config profile if JF_CONFIG_PROFILE is provided.
// If so - it verifies there is only a single module with a '.' path from root. If these conditions doesn't hold we return an error.
func getConfigProfileIfExistsAndValid(jfrogServer *coreconfig.ServerDetails) (configProfile *services.ConfigProfile, err error) {
profileName := getTrimmedEnv(JfrogConfigProfileEnv)
if profileName == "" {
log.Debug(fmt.Sprintf("No %s environment variable was provided. All configurations will be induced from Env vars and files", JfrogConfigProfileEnv))
return
}

if configProfile, err = xsc.GetConfigProfile(jfrogServer, profileName); err != nil {
return
}

// Currently, only a single Module that represents the entire project is supported
if len(configProfile.Modules) != 1 {
err = fmt.Errorf("more than one module was found '%s' profile. Frogbot currently supports only one module per config profile", configProfile.ProfileName)
return
}
if configProfile.Modules[0].PathFromRoot != "." {
err = fmt.Errorf("module '%s' in profile '%s' contains the following path from root: '%s'. Frogbot currently supports only a single module with a '.' path from root", configProfile.Modules[0].ModuleName, profileName, configProfile.Modules[0].PathFromRoot)
return
}
log.Info(fmt.Sprintf("Using Config profile '%s'. jfrog-apps-config will be ignored if exists", profileName))
return
}
48 changes: 48 additions & 0 deletions utils/params_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package utils

import (
"encoding/json"
"errors"
"fmt"
"github.com/jfrog/jfrog-client-go/utils/tests"
"github.com/jfrog/jfrog-client-go/xsc/services"
"os"
"path/filepath"
"testing"
Expand All @@ -17,6 +20,7 @@ import (
var (
configParamsTestFile = filepath.Join("..", "testdata", "config", "frogbot-config-test-params.yml")
configEmptyScanParamsTestFile = filepath.Join("..", "testdata", "config", "frogbot-config-empty-scan.yml")
configProfileFile = filepath.Join("..", "testdata", "configprofile", "configProfileExample.json")
)

func TestExtractParamsFromEnvError(t *testing.T) {
Expand Down Expand Up @@ -678,3 +682,47 @@ func TestSetEmailDetails(t *testing.T) {
})
}
}

func TestGetConfigProfileIfExistsAndValid(t *testing.T) {
testcases := []struct {
profileName string
failureExpected bool
}{
{
profileName: ValidConfigProfile,
failureExpected: false,
},
{
profileName: InvalidPathConfigProfile,
failureExpected: true,
},
{
profileName: InvalidModulesConfigProfile,
failureExpected: true,
},
}

for _, testcase := range testcases {
t.Run(testcase.profileName, func(t *testing.T) {
envCallbackFunc := tests.SetEnvWithCallbackAndAssert(t, JfrogConfigProfileEnv, testcase.profileName)
defer envCallbackFunc()

mockServer, serverDetails := CreateXscMockServerForConfigProfile(t)
defer mockServer.Close()

configProfile, err := getConfigProfileIfExistsAndValid(serverDetails)
if testcase.failureExpected {
assert.Error(t, err)
} else {
assert.NoError(t, err)
var configProfileContentForComparison []byte
configProfileContentForComparison, err = os.ReadFile(configProfileFile)
assert.NoError(t, err)
var configProfileFromFile services.ConfigProfile
err = json.Unmarshal(configProfileContentForComparison, &configProfileFromFile)
assert.NoError(t, err)
assert.Equal(t, configProfileFromFile, *configProfile)
}
})
}
}
10 changes: 9 additions & 1 deletion utils/scandetails.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
clientservices "github.com/jfrog/jfrog-client-go/xsc/services"
"os"
"path/filepath"

Expand All @@ -28,6 +29,7 @@ type ScanDetails struct {
fixableOnly bool
minSeverityFilter severityutils.Severity
baseBranch string
configProfile *clientservices.ConfigProfile
}

func NewScanDetails(client vcsclient.VcsClient, server *config.ServerDetails, git *Git) *ScanDetails {
Expand Down Expand Up @@ -71,6 +73,11 @@ func (sc *ScanDetails) SetBaseBranch(branch string) *ScanDetails {
return sc
}

func (sc *ScanDetails) SetConfigProfile(configProfile *clientservices.ConfigProfile) *ScanDetails {
sc.configProfile = configProfile
return sc
}

func (sc *ScanDetails) Client() vcsclient.VcsClient {
return sc.client
}
Expand Down Expand Up @@ -153,7 +160,8 @@ func (sc *ScanDetails) RunInstallAndAudit(workDirs ...string) (auditResults *xra
SetMinSeverityFilter(sc.MinSeverityFilter()).
SetFixableOnly(sc.FixableOnly()).
SetGraphBasicParams(auditBasicParams).
SetCommonGraphScanParams(sc.CreateCommonGraphScanParams())
SetCommonGraphScanParams(sc.CreateCommonGraphScanParams()).
SetConfigProfile(sc.configProfile)
auditParams.SetExclusions(sc.PathExclusions).SetIsRecursiveScan(sc.IsRecursiveScan)

auditResults, err = audit.RunAudit(auditParams)
Expand Down
Loading

0 comments on commit bce4aee

Please sign in to comment.