diff --git a/artifactory/commands/buildinfo/buildappend.go b/artifactory/commands/buildinfo/buildappend.go index b1128bdda..92fe3b093 100644 --- a/artifactory/commands/buildinfo/buildappend.go +++ b/artifactory/commands/buildinfo/buildappend.go @@ -1,17 +1,20 @@ package buildinfo import ( + "encoding/json" + "errors" "fmt" - "net/url" + "io" "strconv" "time" buildinfo "github.com/jfrog/build-info-go/entities" + "github.com/jfrog/jfrog-client-go/artifactory" + servicesutils "github.com/jfrog/jfrog-client-go/artifactory/services/utils" "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" "github.com/jfrog/jfrog-cli-core/v2/utils/config" "github.com/jfrog/jfrog-client-go/artifactory/services" - "github.com/jfrog/jfrog-client-go/http/httpclient" "github.com/jfrog/jfrog-client-go/utils/errorutils" "github.com/jfrog/jfrog-client-go/utils/log" ) @@ -45,18 +48,24 @@ func (bac *BuildAppendCommand) Run() error { if err != nil { return err } - if err := utils.SaveBuildGeneralDetails(buildName, buildNumber, bac.buildConfiguration.GetProject()); err != nil { + if err = utils.SaveBuildGeneralDetails(buildName, buildNumber, bac.buildConfiguration.GetProject()); err != nil { + return err + } + + // Create services manager to get build-info from Artifactory. + servicesManager, err := utils.CreateServiceManager(bac.serverDetails, -1, 0, false) + if err != nil { return err } // Calculate build timestamp - timestamp, err := bac.getBuildTimestamp() + timestamp, err := bac.getBuildTimestamp(servicesManager) if err != nil { return err } - // Get checksum headers from the build info artifact - checksumDetails, err := bac.getChecksumDetails(timestamp) + // Get checksum values from the build info artifact + checksumDetails, err := bac.getChecksumDetails(servicesManager, timestamp) if err != nil { return err } @@ -99,16 +108,10 @@ func (bac *BuildAppendCommand) SetBuildNumberToAppend(buildNumber string) *Build // Get build timestamp of the build to append. The build timestamp has to be converted to milliseconds from epoch. // For example, start time of: 2020-11-27T14:33:38.538+0200 should be converted to 1606480418538. -func (bac *BuildAppendCommand) getBuildTimestamp() (int64, error) { - // Create services manager to get build-info from Artifactory. - sm, err := utils.CreateServiceManager(bac.serverDetails, -1, 0, false) - if err != nil { - return 0, err - } - +func (bac *BuildAppendCommand) getBuildTimestamp(servicesManager artifactory.ArtifactoryServicesManager) (int64, error) { // Get published build-info from Artifactory. buildInfoParams := services.BuildInfoParams{BuildName: bac.buildNameToAppend, BuildNumber: bac.buildNumberToAppend, ProjectKey: bac.buildConfiguration.GetProject()} - buildInfo, found, err := sm.GetBuildInfo(buildInfoParams) + buildInfo, found, err := servicesManager.GetBuildInfo(buildInfoParams) if err != nil { return 0, err } @@ -133,24 +136,38 @@ func (bac *BuildAppendCommand) getBuildTimestamp() (int64, error) { } // Download MD5 and SHA1 from the build info artifact. -func (bac *BuildAppendCommand) getChecksumDetails(timestamp int64) (buildinfo.Checksum, error) { - serviceDetails, err := bac.serverDetails.CreateArtAuthConfig() +func (bac *BuildAppendCommand) getChecksumDetails(servicesManager artifactory.ArtifactoryServicesManager, timestamp int64) (buildinfo.Checksum, error) { + // Run AQL query for build + stringTimestamp := strconv.FormatInt(timestamp, 10) + aqlQuery := servicesutils.CreateAqlQueryForBuildInfoJson(bac.buildConfiguration.GetProject(), bac.buildNameToAppend, bac.buildNumberToAppend, stringTimestamp) + stream, err := servicesManager.Aql(aqlQuery) if err != nil { return buildinfo.Checksum{}, err } - client, err := httpclient.ClientBuilder().SetRetries(3).Build() + defer func() { + err = errors.Join(err, errorutils.CheckError(stream.Close())) + }() + + // Parse AQL results + aqlResults, err := io.ReadAll(stream) if err != nil { - return buildinfo.Checksum{}, err + return buildinfo.Checksum{}, errorutils.CheckError(err) } - - buildInfoRepo := "artifactory-build-info" - if bac.buildConfiguration.GetProject() != "" { - buildInfoRepo = url.PathEscape(bac.buildConfiguration.GetProject()) + "-build-info" + parsedResult := new(servicesutils.AqlSearchResult) + if err = json.Unmarshal(aqlResults, parsedResult); err != nil { + return buildinfo.Checksum{}, errorutils.CheckError(err) } - buildInfoPath := fmt.Sprintf("%v%v/%v/%v-%v.json", serviceDetails.GetUrl(), buildInfoRepo, url.PathEscape(bac.buildNameToAppend), url.PathEscape(bac.buildNumberToAppend), strconv.FormatInt(timestamp, 10)) - details, _, err := client.GetRemoteFileDetails(buildInfoPath, serviceDetails.CreateHttpClientDetails()) - if err != nil { - return buildinfo.Checksum{}, err + if len(parsedResult.Results) == 0 { + return buildinfo.Checksum{}, errorutils.CheckErrorf("Build '%s/%s' could not be found", bac.buildNameToAppend, bac.buildNumberToAppend) + } + + // Verify checksum exist + sha1 := parsedResult.Results[0].Actual_Sha1 + md5 := parsedResult.Results[0].Actual_Md5 + if sha1 == "" || md5 == "" { + return buildinfo.Checksum{}, errorutils.CheckErrorf("Missing checksums for build-info: '%s/%s', sha1: '%s', md5: '%s'", bac.buildNameToAppend, bac.buildNumberToAppend, sha1, md5) } - return details.Checksum, nil + + // Return checksums + return buildinfo.Checksum{Sha1: sha1, Md5: md5}, nil } diff --git a/artifactory/utils/projectconfig.go b/artifactory/utils/projectconfig.go index 95072e5a3..8bedba779 100644 --- a/artifactory/utils/projectconfig.go +++ b/artifactory/utils/projectconfig.go @@ -17,6 +17,7 @@ const ( ProjectConfigResolverPrefix = "resolver" ProjectConfigDeployerPrefix = "deployer" ProjectConfigRepo = "repo" + ProjectConfigReleaseRepo = "releaseRepo" ProjectConfigServerId = "serverId" ) @@ -130,8 +131,11 @@ func GetRepoConfigByPrefix(configFilePath, prefix string, vConfig *viper.Viper) log.Debug(fmt.Sprintf("Found %s in the config file %s", prefix, configFilePath)) repo := vConfig.GetString(prefix + "." + ProjectConfigRepo) if repo == "" { - err = errorutils.CheckErrorf("missing repository for %s within %s", prefix, configFilePath) - return + // In the maven.yaml config, there's a resolver repository field named "releaseRepo" + if repo = vConfig.GetString(prefix + "." + ProjectConfigReleaseRepo); repo == "" { + err = errorutils.CheckErrorf("missing repository for %s within %s", prefix, configFilePath) + return + } } serverId := vConfig.GetString(prefix + "." + ProjectConfigServerId) if serverId == "" { @@ -194,7 +198,7 @@ func ReadResolutionOnlyConfiguration(confFilePath string) (*RepositoryConfig, er // Verifies the existence of depsRepo. If it doesn't exist, it searches for a configuration file based on the technology type. If found, it assigns depsRepo in the AuditParams. func SetResolutionRepoIfExists(params xrayutils.AuditParams, tech coreutils.Technology) (err error) { - if params.DepsRepo() != "" { + if params.DepsRepo() != "" || params.IgnoreConfigFile() { return } configFilePath, exists, err := GetProjectConfFilePath(techType[tech]) diff --git a/go.mod b/go.mod index 8d3c1df20..bfa158b0f 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/jfrog/build-info-go v1.9.15 github.com/jfrog/gofrog v1.3.1 github.com/jfrog/jfrog-apps-config v1.0.1 - github.com/jfrog/jfrog-client-go v1.34.4 + github.com/jfrog/jfrog-client-go v1.34.5 github.com/magiconair/properties v1.8.7 github.com/manifoldco/promptui v0.9.0 github.com/owenrumney/go-sarif/v2 v2.3.0 @@ -99,6 +99,6 @@ require ( gopkg.in/warnings.v0 v0.1.2 // indirect ) -// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go dev +// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20231109105822-00d80f604090 // replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev diff --git a/go.sum b/go.sum index ec337f552..6d727df69 100644 --- a/go.sum +++ b/go.sum @@ -202,8 +202,8 @@ github.com/jfrog/gofrog v1.3.1 h1:QqAwQXCVReT724uga1AYqG/ZyrNQ6f+iTxmzkb+YFQk= github.com/jfrog/gofrog v1.3.1/go.mod h1:IFMc+V/yf7rA5WZ74CSbXe+Lgf0iApEQLxRZVzKRUR0= 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-client-go v1.34.4 h1:Qt6Yniv48N9EaE0rrUZznOohuDRvqp9sUUHiHXAo3Xs= -github.com/jfrog/jfrog-client-go v1.34.4/go.mod h1:0PVhP6xGvBBaUzOU9LKf5OYkke/gY2IFILHA++iabFM= +github.com/jfrog/jfrog-client-go v1.34.5 h1:NYZrOHvT5D5BwwHdArIz5WnbP+DPbADjV/SPdN33bfQ= +github.com/jfrog/jfrog-client-go v1.34.5/go.mod h1:0PVhP6xGvBBaUzOU9LKf5OYkke/gY2IFILHA++iabFM= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= diff --git a/xray/commands/audit/scarunner.go b/xray/commands/audit/scarunner.go index 17eaa1d9b..2fe21ff4a 100644 --- a/xray/commands/audit/scarunner.go +++ b/xray/commands/audit/scarunner.go @@ -29,7 +29,7 @@ import ( xrayCmdUtils "github.com/jfrog/jfrog-client-go/xray/services/utils" ) -var DefaultExcludePatterns = []string{"*node_modules*", "*target*", "*venv*", "*test*"} +var DefaultExcludePatterns = []string{"*.git*", "*node_modules*", "*target*", "*venv*", "*test*"} func runScaScan(params *AuditParams, results *xrayutils.Results) (err error) { // Prepare diff --git a/xray/commands/audit/scarunner_test.go b/xray/commands/audit/scarunner_test.go index 758db9d3c..2dc44b144 100644 --- a/xray/commands/audit/scarunner_test.go +++ b/xray/commands/audit/scarunner_test.go @@ -138,7 +138,7 @@ func TestGetExcludePattern(t *testing.T) { name: "Test no exclude pattern recursive", params: NewAuditParams, recursive: true, - expected: "(^.*node_modules.*$)|(^.*target.*$)|(^.*venv.*$)|(^.*test.*$)", + expected: "(^.*\\.git.*$)|(^.*node_modules.*$)|(^.*target.*$)|(^.*venv.*$)|(^.*test.*$)", }, { name: "Test exclude pattern not recursive", @@ -154,7 +154,7 @@ func TestGetExcludePattern(t *testing.T) { name: "Test no exclude pattern", params: NewAuditParams, recursive: false, - expected: "(^.*node_modules.*$)|(^.*target.*$)|(^.*venv.*$)|(^.*test.*$)", + expected: "(^.*\\.git.*$)|(^.*node_modules.*$)|(^.*target.*$)|(^.*venv.*$)|(^.*test.*$)", }, } diff --git a/xray/utils/resultwriter.go b/xray/utils/resultwriter.go index 5d7702841..f7ab95f42 100644 --- a/xray/utils/resultwriter.go +++ b/xray/utils/resultwriter.go @@ -330,7 +330,7 @@ func getXrayIssueLocationIfValidExists(tech coreutils.Technology, run *sarif.Run return } if strings.TrimSpace(descriptorPath) == "" { - return + descriptorPath = "Package Descriptor" } return sarif.NewLocation().WithPhysicalLocation(sarif.NewPhysicalLocation().WithArtifactLocation(sarif.NewArtifactLocation().WithUri("file://" + descriptorPath))), nil } diff --git a/xray/utils/resultwriter_test.go b/xray/utils/resultwriter_test.go index b6fa06d11..18d053261 100644 --- a/xray/utils/resultwriter_test.go +++ b/xray/utils/resultwriter_test.go @@ -163,7 +163,7 @@ func TestGetXrayIssueLocationIfValidExists(t *testing.T) { name: "No descriptor information", tech: coreutils.Pip, run: CreateRunWithDummyResults().WithInvocations([]*sarif.Invocation{invocation}), - expectedOutput: nil, + expectedOutput: sarif.NewLocation().WithPhysicalLocation(sarif.NewPhysicalLocation().WithArtifactLocation(sarif.NewArtifactLocation().WithUri("file://Package Descriptor"))), }, { name: "One descriptor information",