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

Added centralized config resolution and utilization for Scan-PR flow #740

Merged
merged 20 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a1a210a
Added new env var const for config profile
eranturgeman Aug 15, 2024
37bee5a
Added a fetching mechanism for config profile + adding the config pro…
eranturgeman Aug 15, 2024
e548f12
Adding config profile to AuditParams
eranturgeman Aug 15, 2024
920d468
Adding config profile to scanDetails
eranturgeman Aug 15, 2024
0ec7549
Merge branch 'dev' of https://github.com/jfrog/frogbot into centraliz…
eranturgeman Aug 15, 2024
4823bbd
added fixes + tests + updated go.mod
eranturgeman Aug 19, 2024
760ccca
Merge branch 'dev' into centralized-config-integration
eranturgeman Aug 19, 2024
28f3376
Merge branch 'dev' of https://github.com/jfrog/frogbot into centraliz…
eranturgeman Aug 19, 2024
cc0cd73
Merge remote-tracking branch 'eran-fork/centralized-config-integratio…
eranturgeman Aug 19, 2024
d6dd448
deleted mock function
eranturgeman Aug 19, 2024
9187b42
fixed static analysis notes
eranturgeman Aug 20, 2024
78bdcee
update go.mod
eranturgeman Aug 21, 2024
172a6e4
update go.mod
eranturgeman Aug 25, 2024
0a8b234
Fixed most CR comments, one thing remain to resolve
eranturgeman Aug 29, 2024
23e8147
Deleted duplicate function and changed usage
eranturgeman Sep 1, 2024
b0094b8
Merge branch 'dev' of https://github.com/jfrog/frogbot into centraliz…
eranturgeman Sep 4, 2024
d8f0a86
updating go.mod
eranturgeman Sep 4, 2024
31ac0d8
Merge branch 'dev' of https://github.com/jfrog/frogbot into centraliz…
eranturgeman Sep 4, 2024
f997b60
updating go.mod with latest releases
eranturgeman Sep 4, 2024
1ede165
fixing broken test due to recent merge to frogbot
eranturgeman Sep 5, 2024
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
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
Loading