From a664ea439478a734223b64000105654c657470d9 Mon Sep 17 00:00:00 2001 From: Omer Zidkoni <50792403+omerzi@users.noreply.github.com> Date: Wed, 5 Apr 2023 09:49:30 +0300 Subject: [PATCH 01/10] Promote version to 1.28.1 (#733) --- .github/workflows/analysis.yml | 4 +- .github/workflows/frogbot-fix.yml | 6 +- .github/workflows/frogbot-scan-pr.yml | 6 +- .github/workflows/tests.yml | 10 ++-- artifactory/services/createreplication.go | 5 +- artifactory/services/utils/aqlquerybuilder.go | 4 +- .../services/utils/aqlquerybuilder_test.go | 36 ++++++------ .../services/utils/artifactoryutils.go | 6 +- artifactory/services/utils/deleteutils.go | 2 +- .../services/utils/deleteutils_test.go | 34 +++++------ artifactory/services/utils/properties.go | 2 +- .../services/utils/releasebundleutils.go | 4 +- .../services/utils/repopathfile_test.go | 6 +- artifactory/services/utils/searchutil_test.go | 6 +- auth/cert/loader.go | 1 - .../services/utils/distributionutils_test.go | 2 +- go.mod | 6 +- go.sum | 11 +++- pipelines/services/run.go | 12 ++-- tests/artifactorypermissiontarget_test.go | 12 ++-- tests/artifactorysystem_test.go | 12 ++-- tests/utils_test.go | 2 +- tests/xrayscan_test.go | 2 +- tests/xraysummary_test.go | 4 +- utils/io/content/contentwriter.go | 2 +- utils/io/fileutils/files.go | 56 +++++++++++++------ utils/utils.go | 13 +++-- xray/services/scan.go | 20 +++++++ xray/services/scan_test.go | 31 ++++++++++ 29 files changed, 198 insertions(+), 119 deletions(-) diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml index ec02d745f..d376be5c4 100644 --- a/.github/workflows/analysis.yml +++ b/.github/workflows/analysis.yml @@ -9,7 +9,7 @@ jobs: - name: Install Go uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - name: Static Code Analysis uses: dominikh/staticcheck-action@v1 with: @@ -23,7 +23,7 @@ jobs: - name: Install Go uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - name: Install gosec run: curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(go env GOPATH)/bin - name: Run gosec diff --git a/.github/workflows/frogbot-fix.yml b/.github/workflows/frogbot-fix.yml index 5782a988a..3a25fb26c 100644 --- a/.github/workflows/frogbot-fix.yml +++ b/.github/workflows/frogbot-fix.yml @@ -13,18 +13,18 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - uses: jfrog/frogbot@v2 env: # [Mandatory] # JFrog platform URL JF_URL: ${{ secrets.FROGBOT_URL }} - + # [Mandatory if JF_USER and JF_PASSWORD are not provided] # JFrog access token with 'read' permissions on Xray service JF_ACCESS_TOKEN: ${{ secrets.FROGBOT_ACCESS_TOKEN }} - + # [Mandatory] # The GitHub token automatically generated for the job JF_GIT_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/frogbot-scan-pr.yml b/.github/workflows/frogbot-scan-pr.yml index b5f224aab..8b61e89d1 100644 --- a/.github/workflows/frogbot-scan-pr.yml +++ b/.github/workflows/frogbot-scan-pr.yml @@ -17,18 +17,18 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - uses: jfrog/frogbot@v2 env: # [Mandatory] # JFrog platform URL JF_URL: ${{ secrets.FROGBOT_URL }} - + # [Mandatory if JF_USER and JF_PASSWORD are not provided] # JFrog access token with 'read' permissions on Xray service JF_ACCESS_TOKEN: ${{ secrets.FROGBOT_ACCESS_TOKEN }} - + # [Mandatory] # The GitHub token automatically generated for the job JF_GIT_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1fbbb98f5..88e0bb1f2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,7 +28,7 @@ jobs: - name: Install Go uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - name: Go Cache uses: actions/cache@v3 @@ -53,7 +53,7 @@ jobs: - name: Install Go uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - name: Checkout code uses: actions/checkout@v3 @@ -96,7 +96,7 @@ jobs: - name: Install Go uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - name: Go Cache uses: actions/cache@v3 @@ -121,7 +121,7 @@ jobs: - name: Install Go uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - name: Go Cache uses: actions/cache@v3 @@ -141,7 +141,7 @@ jobs: - name: Install Go uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - name: Checkout code uses: actions/checkout@v3 diff --git a/artifactory/services/createreplication.go b/artifactory/services/createreplication.go index ad91cb1f7..bec1b172b 100644 --- a/artifactory/services/createreplication.go +++ b/artifactory/services/createreplication.go @@ -32,8 +32,7 @@ func (rs *CreateReplicationService) performRequest(params *utils.UpdateReplicati httpClientsDetails := rs.ArtDetails.CreateHttpClientDetails() utils.SetContentType("application/vnd.org.jfrog.artifactory.replications.ReplicationConfigRequest+json", &httpClientsDetails.Headers) var url = rs.ArtDetails.GetUrl() + "api/replications/" + params.RepoKey - log.Info("Creating replication..") - operationString := "creating" + log.Info("Creating replication...") resp, body, err := rs.client.SendPut(url, content, &httpClientsDetails) if err != nil { return err @@ -42,7 +41,7 @@ func (rs *CreateReplicationService) performRequest(params *utils.UpdateReplicati return err } log.Debug("Artifactory response:", resp.Status) - log.Info("Done " + operationString + " repository.") + log.Info("Done creating replication.") return nil } diff --git a/artifactory/services/utils/aqlquerybuilder.go b/artifactory/services/utils/aqlquerybuilder.go index fb5ae0619..88e1c7a53 100644 --- a/artifactory/services/utils/aqlquerybuilder.go +++ b/artifactory/services/utils/aqlquerybuilder.go @@ -163,8 +163,8 @@ func CreateAqlQueryForLatestCreated(repo, path string) string { func prepareSearchPattern(pattern string, repositoryExists bool) string { addWildcardIfNeeded(&pattern, repositoryExists) // Remove parenthesis - pattern = strings.Replace(pattern, "(", "", -1) - pattern = strings.Replace(pattern, ")", "", -1) + pattern = strings.ReplaceAll(pattern, "(", "") + pattern = strings.ReplaceAll(pattern, ")", "") return pattern } diff --git a/artifactory/services/utils/aqlquerybuilder_test.go b/artifactory/services/utils/aqlquerybuilder_test.go index 916a8b2a6..62502ce52 100644 --- a/artifactory/services/utils/aqlquerybuilder_test.go +++ b/artifactory/services/utils/aqlquerybuilder_test.go @@ -47,26 +47,26 @@ func TestBuildAqlSearchQuery(t *testing.T) { func TestCommonParams(t *testing.T) { artifactoryParams := CommonParams{} - assertIsSortLimitSpecBool(!includePropertiesInAqlForSpec(&artifactoryParams), false, t) + assertIsSortLimitSpecBool(t, !includePropertiesInAqlForSpec(&artifactoryParams), false) artifactoryParams.SortBy = []string{"Vava", "Bubu"} - assertIsSortLimitSpecBool(!includePropertiesInAqlForSpec(&artifactoryParams), true, t) + assertIsSortLimitSpecBool(t, !includePropertiesInAqlForSpec(&artifactoryParams), true) artifactoryParams.SortBy = nil artifactoryParams.Limit = 0 - assertIsSortLimitSpecBool(!includePropertiesInAqlForSpec(&artifactoryParams), false, t) + assertIsSortLimitSpecBool(t, !includePropertiesInAqlForSpec(&artifactoryParams), false) artifactoryParams.Limit = -3 - assertIsSortLimitSpecBool(!includePropertiesInAqlForSpec(&artifactoryParams), false, t) + assertIsSortLimitSpecBool(t, !includePropertiesInAqlForSpec(&artifactoryParams), false) artifactoryParams.Limit = 3 - assertIsSortLimitSpecBool(!includePropertiesInAqlForSpec(&artifactoryParams), true, t) + assertIsSortLimitSpecBool(t, !includePropertiesInAqlForSpec(&artifactoryParams), true) artifactoryParams.SortBy = []string{"Vava", "Bubu"} - assertIsSortLimitSpecBool(!includePropertiesInAqlForSpec(&artifactoryParams), true, t) + assertIsSortLimitSpecBool(t, !includePropertiesInAqlForSpec(&artifactoryParams), true) } -func assertIsSortLimitSpecBool(actual, expected bool, t *testing.T) { +func assertIsSortLimitSpecBool(t *testing.T, actual, expected bool) { if actual != expected { t.Error("The function includePropertiesInAqlForSpec() expected to return " + strconv.FormatBool(expected) + " but returned " + strconv.FormatBool(actual) + ".") } @@ -76,20 +76,20 @@ func TestGetQueryReturnFields(t *testing.T) { artifactoryParams := CommonParams{} minimalFields := []string{"name", "repo", "path", "actual_md5", "actual_sha1", "sha256", "size", "type", "created", "modified"} - assertEqualFieldsList(getQueryReturnFields(&artifactoryParams, ALL), append(minimalFields, "property"), t) - assertEqualFieldsList(getQueryReturnFields(&artifactoryParams, SYMLINK), append(minimalFields, "property"), t) - assertEqualFieldsList(getQueryReturnFields(&artifactoryParams, NONE), minimalFields, t) + assertEqualFieldsList(t, getQueryReturnFields(&artifactoryParams, ALL), append(minimalFields, "property")) + assertEqualFieldsList(t, getQueryReturnFields(&artifactoryParams, SYMLINK), append(minimalFields, "property")) + assertEqualFieldsList(t, getQueryReturnFields(&artifactoryParams, NONE), minimalFields) artifactoryParams.SortBy = []string{"Vava"} - assertEqualFieldsList(getQueryReturnFields(&artifactoryParams, NONE), append(minimalFields, "Vava"), t) - assertEqualFieldsList(getQueryReturnFields(&artifactoryParams, ALL), append(minimalFields, "Vava"), t) - assertEqualFieldsList(getQueryReturnFields(&artifactoryParams, SYMLINK), append(minimalFields, "Vava"), t) + assertEqualFieldsList(t, getQueryReturnFields(&artifactoryParams, NONE), append(minimalFields, "Vava")) + assertEqualFieldsList(t, getQueryReturnFields(&artifactoryParams, ALL), append(minimalFields, "Vava")) + assertEqualFieldsList(t, getQueryReturnFields(&artifactoryParams, SYMLINK), append(minimalFields, "Vava")) artifactoryParams.SortBy = []string{"Vava", "Bubu"} - assertEqualFieldsList(getQueryReturnFields(&artifactoryParams, ALL), append(minimalFields, "Vava", "Bubu"), t) + assertEqualFieldsList(t, getQueryReturnFields(&artifactoryParams, ALL), append(minimalFields, "Vava", "Bubu")) } -func assertEqualFieldsList(actual, expected []string, t *testing.T) { +func assertEqualFieldsList(t *testing.T, actual, expected []string) { if len(actual) != len(expected) { t.Error("The function getQueryReturnFields() expected to return the array:\n" + strings.Join(expected[:], ",") + ".\nbut returned:\n" + strings.Join(actual[:], ",") + ".") } @@ -109,11 +109,11 @@ func assertEqualFieldsList(actual, expected []string, t *testing.T) { } func TestBuildSortBody(t *testing.T) { - assertSortBody(buildSortQueryPart([]string{"bubu"}, ""), `"$asc":["bubu"]`, t) - assertSortBody(buildSortQueryPart([]string{"bubu", "kuku"}, ""), `"$asc":["bubu","kuku"]`, t) + assertSortBody(t, buildSortQueryPart([]string{"bubu"}, ""), `"$asc":["bubu"]`) + assertSortBody(t, buildSortQueryPart([]string{"bubu", "kuku"}, ""), `"$asc":["bubu","kuku"]`) } -func assertSortBody(actual, expected string, t *testing.T) { +func assertSortBody(t *testing.T, actual, expected string) { if actual != expected { t.Error("The function buildSortQueryPart expected to return the string:\n'" + expected + "'.\nbut returned:\n'" + actual + "'.") } diff --git a/artifactory/services/utils/artifactoryutils.go b/artifactory/services/utils/artifactoryutils.go index a851f152c..6fa0c8b6f 100644 --- a/artifactory/services/utils/artifactoryutils.go +++ b/artifactory/services/utils/artifactoryutils.go @@ -107,7 +107,7 @@ func BuildArtifactoryUrl(baseUrl, path string, params map[string]string) (string parsedUrl.RawQuery = q.Encode() // Semicolons are reserved as separators in some Artifactory APIs, so they'd better be encoded when used for other purposes - encodedUrl := strings.Replace(parsedUrl.String(), ";", url.QueryEscape(";"), -1) + encodedUrl := strings.ReplaceAll(parsedUrl.String(), ";", url.QueryEscape(";")) return encodedUrl, nil } @@ -227,8 +227,8 @@ func ParseNameAndVersion(identifier string, useLatestPolicy bool) (string, strin } } // Remove escape chars. - name = strings.Replace(name, "\\/", "/", -1) - version = strings.Replace(version, "\\/", "/", -1) + name = strings.ReplaceAll(name, "\\/", "/") + version = strings.ReplaceAll(version, "\\/", "/") return name, version, nil } diff --git a/artifactory/services/utils/deleteutils.go b/artifactory/services/utils/deleteutils.go index 7d404e613..f19d6f537 100644 --- a/artifactory/services/utils/deleteutils.go +++ b/artifactory/services/utils/deleteutils.go @@ -15,7 +15,7 @@ func WildcardToDirsPath(deletePattern, searchResult string) (string, error) { return "", errors.New("delete pattern must end with \"/\"") } - regexpPattern := "^" + strings.Replace(deletePattern, "*", "([^/]*|.*)", -1) + regexpPattern := "^" + strings.ReplaceAll(deletePattern, "*", "([^/]*|.*)") r, err := regexp.Compile(regexpPattern) if err != nil { return "", errorutils.CheckError(err) diff --git a/artifactory/services/utils/deleteutils_test.go b/artifactory/services/utils/deleteutils_test.go index 65e5061f6..ce197ad15 100644 --- a/artifactory/services/utils/deleteutils_test.go +++ b/artifactory/services/utils/deleteutils_test.go @@ -14,44 +14,44 @@ import ( func TestMatchingDelete(t *testing.T) { var actual string actual, _ = WildcardToDirsPath("s/*/path/", "s/a/path/b.zip") - assertDeletePattern("s/a/path/", actual, t) + assertDeletePattern(t, "s/a/path/", actual) actual, _ = WildcardToDirsPath("s/*/path/", "s/a/b/c/path/b.zip") - assertDeletePattern("s/a/b/c/path/", actual, t) + assertDeletePattern(t, "s/a/b/c/path/", actual) actual, _ = WildcardToDirsPath("s/a/*/", "s/a/b/path/b.zip") - assertDeletePattern("s/a/b/", actual, t) + assertDeletePattern(t, "s/a/b/", actual) actual, _ = WildcardToDirsPath("s/*/path/*/", "s/a/path/a/b.zip") - assertDeletePattern("s/a/path/a/", actual, t) + assertDeletePattern(t, "s/a/path/a/", actual) actual, _ = WildcardToDirsPath("s/*/path/*/", "s/a/a/path/a/b/c/d/b.zip") - assertDeletePattern("s/a/a/path/a/", actual, t) + assertDeletePattern(t, "s/a/a/path/a/", actual) actual, _ = WildcardToDirsPath("s/*/", "s/a/a/path/a/b/c/d/b.zip") - assertDeletePattern("s/a/", actual, t) + assertDeletePattern(t, "s/a/", actual) actual, _ = WildcardToDirsPath("s/*/a/*/", "s/a/a/path/k/b/c/d/b.zip") - assertDeletePattern("s/a/a/path/", actual, t) + assertDeletePattern(t, "s/a/a/path/", actual) actual, _ = WildcardToDirsPath("s/*/a/*/*/", "s/a/a/path/k/b/c/d/b.zip") - assertDeletePattern("s/a/a/path/k/", actual, t) + assertDeletePattern(t, "s/a/a/path/k/", actual) actual, _ = WildcardToDirsPath("s/*/*l*/*/*/", "s/a/l/path/k/b/c/d/b.zip") - assertDeletePattern("s/a/l/path/k/", actual, t) + assertDeletePattern(t, "s/a/l/path/k/", actual) actual, _ = WildcardToDirsPath("s/*/a*/", "s/a/a/path/k/b/c/d/b.zip") - assertDeletePattern("s/a/a/", actual, t) + assertDeletePattern(t, "s/a/a/", actual) actual, _ = WildcardToDirsPath("s/a*/", "s/a/a/path/k/b/c/d/b.zip") - assertDeletePattern("s/a/", actual, t) + assertDeletePattern(t, "s/a/", actual) actual, _ = WildcardToDirsPath("s/*/", "s/a/a/path/k/b/c/d/b.zip") - assertDeletePattern("s/a/", actual, t) + assertDeletePattern(t, "s/a/", actual) actual, _ = WildcardToDirsPath("s/*/*path*/", "s/a/h/path/k/b/c/d/b.zip") - assertDeletePattern("s/a/h/path/", actual, t) + assertDeletePattern(t, "s/a/h/path/", actual) actual, _ = WildcardToDirsPath("a/b/*********/*******/", "a/b/c/d/e.zip") - assertDeletePattern("a/b/c/d/", actual, t) + assertDeletePattern(t, "a/b/c/d/", actual) _, err := WildcardToDirsPath("s/*/a/*/*", "s/a/a/path/k/b/c/d/b.zip") - assertDeletePatternErr("delete pattern must end with \"/\"", err.Error(), t) + assertDeletePatternErr(t, "delete pattern must end with \"/\"", err.Error()) } -func assertDeletePattern(expected, actual string, t *testing.T) { +func assertDeletePattern(t *testing.T, expected, actual string) { if expected != actual { t.Error("Wrong matching expected: `" + expected + "` Got `" + actual + "`") } } -func assertDeletePatternErr(expected, actual string, t *testing.T) { +func assertDeletePatternErr(t *testing.T, expected, actual string) { if expected != actual { t.Error("Wrong err message expected: `" + expected + "` Got `" + actual + "`") } diff --git a/artifactory/services/utils/properties.go b/artifactory/services/utils/properties.go index bfc682b33..f91724916 100644 --- a/artifactory/services/utils/properties.go +++ b/artifactory/services/utils/properties.go @@ -121,7 +121,7 @@ func (props *Properties) ToEncodedString(concatValues bool) string { } for _, value := range values { if concatValues { - propValue := strings.Replace(value, multiValuesSeparator, fmt.Sprintf("\\%s", multiValuesSeparator), -1) + propValue := strings.ReplaceAll(value, multiValuesSeparator, fmt.Sprintf("\\%s", multiValuesSeparator)) jointProp = fmt.Sprintf("%s%s%s", jointProp, url.QueryEscape(propValue), url.QueryEscape(multiValuesSeparator)) } else { jointProp = fmt.Sprintf("%s%s=%s%s", jointProp, url.QueryEscape(key), url.QueryEscape(value), propsSeparator) diff --git a/artifactory/services/utils/releasebundleutils.go b/artifactory/services/utils/releasebundleutils.go index 72ce49f04..7097876f3 100644 --- a/artifactory/services/utils/releasebundleutils.go +++ b/artifactory/services/utils/releasebundleutils.go @@ -2,11 +2,11 @@ package utils import ( "fmt" - jwt "github.com/golang-jwt/jwt/v4" + "github.com/ProtonMail/go-crypto/openpgp" + "github.com/golang-jwt/jwt/v4" "github.com/jfrog/jfrog-client-go/auth" "github.com/jfrog/jfrog-client-go/http/jfroghttpclient" "github.com/jfrog/jfrog-client-go/utils/errorutils" - "golang.org/x/crypto/openpgp" "os" "path/filepath" "strings" diff --git a/artifactory/services/utils/repopathfile_test.go b/artifactory/services/utils/repopathfile_test.go index 51ca4699d..de9d30719 100644 --- a/artifactory/services/utils/repopathfile_test.go +++ b/artifactory/services/utils/repopathfile_test.go @@ -90,7 +90,7 @@ var repoPathFilesDataProvider = []createRepoPathFileTriplesTest{ func TestCreatePathFilePairs(t *testing.T) { for _, sample := range pathFilesDataProvider { t.Run(sample.pattern+"_recursive_"+strconv.FormatBool(sample.recursive), func(t *testing.T) { - validateRepoPathFile(createPathFilePairs("r", sample.pattern, sample.recursive), sample.expectedTriples, sample.pattern, t) + validateRepoPathFile(t, createPathFilePairs("r", sample.pattern, sample.recursive), sample.expectedTriples, sample.pattern) }) } } @@ -101,12 +101,12 @@ func TestCreateRepoPathFileTriples(t *testing.T) { repoPathFileTriples, singleRepo, err := createRepoPathFileTriples(sample.pattern, sample.recursive) assert.NoError(t, err) assert.Equal(t, sample.expectedSingleRepo, singleRepo) - validateRepoPathFile(repoPathFileTriples, sample.expectedTriples, sample.pattern, t) + validateRepoPathFile(t, repoPathFileTriples, sample.expectedTriples, sample.pattern) }) } } -func validateRepoPathFile(actual, expected []RepoPathFile, pattern string, t *testing.T) { +func validateRepoPathFile(t *testing.T, actual, expected []RepoPathFile, pattern string) { if len(actual) != len(expected) { t.Errorf("Wrong triple.\nPattern: %v\nExpected: %v\nActual: %v", pattern, expected, actual) } diff --git a/artifactory/services/utils/searchutil_test.go b/artifactory/services/utils/searchutil_test.go index 987309b48..637a6b310 100644 --- a/artifactory/services/utils/searchutil_test.go +++ b/artifactory/services/utils/searchutil_test.go @@ -68,7 +68,7 @@ func TestReduceTopChainDirResult(t *testing.T) { oldMaxSize := utils.MaxBufferSize defer func() { utils.MaxBufferSize = oldMaxSize }() - //Test buffer + sort + // Test buffer + sort utils.MaxBufferSize = 3 reader = content.NewContentReader(filepath.Join(testDataPath, "reduce_top_chain_step4.json"), content.DefaultKey) resultReader, err = ReduceTopChainDirResult(ResultItem{}, reader) @@ -79,7 +79,7 @@ func TestReduceTopChainDirResult(t *testing.T) { assert.True(t, isMatch) readerCloseAndAssert(t, resultReader) - //Two files in the same folder and one is a prefix to another. + // Two files in the same folder and one is a prefix to another. reader = content.NewContentReader(filepath.Join(testDataPath, "reduce_top_chain_step5.json"), content.DefaultKey) resultReader, err = ReduceTopChainDirResult(ResultItem{}, reader) assert.NoError(t, err) @@ -89,7 +89,7 @@ func TestReduceTopChainDirResult(t *testing.T) { assert.True(t, isMatch) readerCloseAndAssert(t, resultReader) - //Two files in the same folder and one is a prefix to another and their folder. + // Two files in the same folder and one is a prefix to another and their folder. reader = content.NewContentReader(filepath.Join(testDataPath, "reduce_top_chain_step6.json"), content.DefaultKey) resultReader, err = ReduceTopChainDirResult(ResultItem{}, reader) assert.NoError(t, err) diff --git a/auth/cert/loader.go b/auth/cert/loader.go index c12eebdad..b8afcd915 100644 --- a/auth/cert/loader.go +++ b/auth/cert/loader.go @@ -60,7 +60,6 @@ func GetTransportWithLoadedCert(certificatesDirPath string, insecureTls bool, tr ClientSessionCache: tls.NewLRUClientSessionCache(1), InsecureSkipVerify: insecureTls, } - transport.TLSClientConfig.BuildNameToCertificate() return transport, nil } diff --git a/distribution/services/utils/distributionutils_test.go b/distribution/services/utils/distributionutils_test.go index ae4adab3f..c99d1ae2c 100644 --- a/distribution/services/utils/distributionutils_test.go +++ b/distribution/services/utils/distributionutils_test.go @@ -24,7 +24,7 @@ func TestCreateBundleBody(t *testing.T) { assert.Equal(t, "storing-repo", releaseBundleBody.StoringRepository) assert.Equal(t, "Release bundle description", releaseBundleBody.Description) assert.Equal(t, "Release notes", releaseBundleBody.ReleaseNotes.Content) - assert.Equal(t, ReleaseNotesSyntax(Asciidoc), releaseBundleBody.ReleaseNotes.Syntax) + assert.Equal(t, Asciidoc, releaseBundleBody.ReleaseNotes.Syntax) assert.Len(t, releaseBundleBody.BundleSpec.Queries, 0) } diff --git a/go.mod b/go.mod index c6c0ad6dc..63aa633af 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,9 @@ module github.com/jfrog/jfrog-client-go -go 1.19 +go 1.20 require ( + github.com/ProtonMail/go-crypto v0.0.0-20230331115716-d34776aa93ec github.com/buger/jsonparser v1.1.1 github.com/forPelevin/gomoji v1.1.8 github.com/go-git/go-git/v5 v5.6.1 @@ -21,7 +22,6 @@ require ( require ( github.com/CycloneDX/cyclonedx-go v0.7.0 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect github.com/acomagu/bufpipe v1.0.4 // indirect github.com/andybalholm/brotli v1.0.1 // indirect github.com/cloudflare/circl v1.1.0 // indirect @@ -55,6 +55,6 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect ) -// replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go v1.8.9-0.20230330091550-a452f54ba1cc +replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go v1.8.9-0.20230403064815-ea83b399ac8e // replace github.com/jfrog/gofrog => github.com/jfrog/gofrog v1.2.5-0.20221107113836-a4c9225c690e diff --git a/go.sum b/go.sum index 82a562a02..05c435ea6 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,9 @@ github.com/CycloneDX/cyclonedx-go v0.7.0 h1:jNxp8hL7UpcvPDFXjY+Y1ibFtsW+e5zyF9Qo github.com/CycloneDX/cyclonedx-go v0.7.0/go.mod h1:W5Z9w8pTTL+t+yG3PCiFRGlr8PUlE0pGWzKSJbsyXkg= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= +github.com/ProtonMail/go-crypto v0.0.0-20230331115716-d34776aa93ec h1:eQusauqzE1cAFR5hGnwkuSmFxKoy3+j9/cVaDeYfjjs= +github.com/ProtonMail/go-crypto v0.0.0-20230331115716-d34776aa93ec/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= @@ -54,8 +55,8 @@ github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= -github.com/jfrog/build-info-go v1.9.0 h1:gLxBfp4C6pVz+bKTmsqwFGZAueVMuzGw+/M9HZgtGG4= -github.com/jfrog/build-info-go v1.9.0/go.mod h1:dQ8OKddrbgtO3jK9uLYoqmRGNEjuDuNXV0bSRdpeTCI= +github.com/jfrog/build-info-go v1.8.9-0.20230403064815-ea83b399ac8e h1:MB5u0Kbq9IIDIlnpDYUq+SHTZ+/ossTOCK7z/t8S0l8= +github.com/jfrog/build-info-go v1.8.9-0.20230403064815-ea83b399ac8e/go.mod h1:HIrpwf4p4XHpAx+N+rb8SX9yrWYWs7X4rT/s0GOJfW8= github.com/jfrog/gofrog v1.2.5 h1:jCgJC0iGQ8bU7jCC+YEFJTNINyngApIrhd8BjZAVRIE= github.com/jfrog/gofrog v1.2.5/go.mod h1:o00tSRff6IapTgaCMuX1Cs9MH08Y1JqnsKgRtx91Gc4= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= @@ -135,6 +136,7 @@ golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAb golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -147,6 +149,7 @@ golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -180,10 +183,12 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pipelines/services/run.go b/pipelines/services/run.go index 8eae4c2d7..fe766a844 100644 --- a/pipelines/services/run.go +++ b/pipelines/services/run.go @@ -25,13 +25,11 @@ func NewRunService(client *jfroghttpclient.JfrogHttpClient) *RunService { } const ( - runStatus = "api/v1/search/pipelines/" - triggerpipeline = "api/v1/pipelines/trigger" - pipelineSyncStatus = "api/v1/pipelineSyncStatuses" - pipelineResources = "api/v1/pipelineSources" - cancelRunPath = "api/v1/runs/:runId/cancel" - syncPipelineResource = "api/v1/pipelineSources" - resourceVersions = "api/v1/resourceVersions" + runStatus = "api/v1/search/pipelines/" + triggerpipeline = "api/v1/pipelines/trigger" + pipelineSyncStatus = "api/v1/pipelineSyncStatuses" + pipelineResources = "api/v1/pipelineSources" + cancelRunPath = "api/v1/runs/:runId/cancel" ) func (rs *RunService) GetRunStatus(branch, pipeName string, isMultiBranch bool) (*PipelineRunStatusResponse, error) { diff --git a/tests/artifactorypermissiontarget_test.go b/tests/artifactorypermissiontarget_test.go index 7ad1246d4..74ea398e9 100644 --- a/tests/artifactorypermissiontarget_test.go +++ b/tests/artifactorypermissiontarget_test.go @@ -159,7 +159,7 @@ func TestDocumentationExampleCreateUpdateAndDeletePermissionTarget(t *testing.T) } func createRandomUser(t *testing.T) string { - name := fmt.Sprintf("test-%s-%s", timestampStr, randomString(16)) + name := fmt.Sprintf("test-%s-%s", timestampStr, randomString(t, 16)) userDetails := services.User{ Name: name, Email: name + "@jfrog.com", @@ -186,20 +186,19 @@ func createRandomUser(t *testing.T) string { } func createRandomRepo(t *testing.T) string { - repoKey := fmt.Sprintf("test-%s-%s", timestampStr, randomString(16)) + repoKey := fmt.Sprintf("test-%s-%s", timestampStr, randomString(t, 16)) glp := services.NewGenericLocalRepositoryParams() glp.Key = repoKey setLocalRepositoryBaseParams(&glp.LocalRepositoryBaseParams, false) err := testsCreateLocalRepositoryService.Generic(glp) - assert.NoError(t, err) return repoKey } func createRandomGroup(t *testing.T) string { - name := fmt.Sprintf("test-%s-%s", timestampStr, randomString(16)) + name := fmt.Sprintf("test-%s-%s", timestampStr, randomString(t, 16)) groupDetails := services.Group{ Name: name, @@ -221,8 +220,9 @@ func createRandomGroup(t *testing.T) string { return name } -func randomString(length int) string { +func randomString(t *testing.T, length int) string { b := make([]byte, length) - rand.Read(b) + _, err := rand.Read(b) + assert.NoError(t, err) return fmt.Sprintf("%x", b)[:length] } diff --git a/tests/artifactorysystem_test.go b/tests/artifactorysystem_test.go index 2cc2fdece..c31b20303 100644 --- a/tests/artifactorysystem_test.go +++ b/tests/artifactorysystem_test.go @@ -50,7 +50,8 @@ func testGetConfigDescriptor(t *testing.T) { // Send response 200 OK w.WriteHeader(http.StatusOK) - w.Write([]byte("")) + _, err := w.Write([]byte("")) + assert.NoError(t, err) }) ts := httptest.NewServer(handler) defer ts.Close() @@ -71,7 +72,8 @@ func testActivateKeyEncryption(t *testing.T) { // Send response 200 OK w.WriteHeader(http.StatusOK) - w.Write([]byte("Done")) + _, err := w.Write([]byte("Done")) + assert.NoError(t, err) }) ts := httptest.NewServer(handler) defer ts.Close() @@ -90,7 +92,8 @@ func testDeactivateKeyEncryption(t *testing.T) { // Send response 200 OK w.WriteHeader(http.StatusOK) - w.Write([]byte("Done")) + _, err := w.Write([]byte("Done")) + assert.NoError(t, err) }) ts := httptest.NewServer(handler) defer ts.Close() @@ -111,7 +114,8 @@ func testDeactivateKeyEncryptionNotEncrypted(t *testing.T) { // Send response 200 OK w.WriteHeader(http.StatusConflict) - w.Write([]byte("Cannot decrypt without artifactory key file")) + _, err := w.Write([]byte("Cannot decrypt without artifactory key file")) + assert.NoError(t, err) }) ts := httptest.NewServer(handler) defer ts.Close() diff --git a/tests/utils_test.go b/tests/utils_test.go index 837dd5649..9c6d006bb 100644 --- a/tests/utils_test.go +++ b/tests/utils_test.go @@ -678,7 +678,7 @@ func teardownIntegrationTests() { repo := getRtTargetRepoKey() err := testsDeleteRepositoryService.Delete(repo) if err != nil { - fmt.Printf("teardownIntegrationTests failed for:" + err.Error()) + fmt.Print("teardownIntegrationTests failed for:" + err.Error()) os.Exit(1) } } diff --git a/tests/xrayscan_test.go b/tests/xrayscan_test.go index e14131e67..687f75057 100644 --- a/tests/xrayscan_test.go +++ b/tests/xrayscan_test.go @@ -55,7 +55,7 @@ func scanBuild(t *testing.T, buildName, buildNumber, expected string) { t.Error(err) } - expected = strings.Replace(expected, "\n", "", -1) + expected = strings.ReplaceAll(expected, "\n", "") if string(result) != expected { t.Error("Expected:", string(result), "Got: ", expected) } diff --git a/tests/xraysummary_test.go b/tests/xraysummary_test.go index 72b96a3c2..f5d7ea4f3 100644 --- a/tests/xraysummary_test.go +++ b/tests/xraysummary_test.go @@ -3,6 +3,7 @@ package tests import ( "bytes" "encoding/json" + "github.com/stretchr/testify/assert" "strconv" "strings" "testing" @@ -63,7 +64,8 @@ func artifactSummary(t *testing.T, checksums []string, paths []string, expected } buf := bytes.NewBuffer([]byte{}) - json.Compact(buf, []byte(expected)) + err = json.Compact(buf, []byte(expected)) + assert.NoError(t, err) expected = buf.String() expected = strings.ReplaceAll(expected, "\n", "") diff --git a/utils/io/content/contentwriter.go b/utils/io/content/contentwriter.go index 3eaaaea62..4918dc8c7 100644 --- a/utils/io/content/contentwriter.go +++ b/utils/io/content/contentwriter.go @@ -149,7 +149,7 @@ func (rw *ContentWriter) run() { firstRecord = false } } - closeString = closeString + jsonArraySuffix + closeString += jsonArraySuffix if rw.isCompleteFile { closeString += "}\n" } diff --git a/utils/io/fileutils/files.go b/utils/io/fileutils/files.go index 2e8e3d105..b85be9b0f 100644 --- a/utils/io/fileutils/files.go +++ b/utils/io/fileutils/files.go @@ -77,13 +77,13 @@ func GetFileInfo(path string, preserveSymLink bool) (fileInfo os.FileInfo, err e fileInfo, err = os.Stat(path) } // We should not do CheckError here, because the error is checked by the calling functions. - return fileInfo, err + return } func IsDirEmpty(path string) (isEmpty bool, err error) { dir, err := os.Open(path) - if err != nil { - return false, errorutils.CheckError(err) + if errorutils.CheckError(err) != nil { + return } defer func() { e := dir.Close() @@ -94,9 +94,12 @@ func IsDirEmpty(path string) (isEmpty bool, err error) { _, err = dir.Readdirnames(1) if err == io.EOF { - return true, nil + isEmpty = true + err = nil + return } - return false, errorutils.CheckError(err) + err = errorutils.CheckError(err) + return } func IsPathSymlink(path string) bool { @@ -282,16 +285,17 @@ func CreateDirIfNotExist(path string) error { // Reads the content of the file in the source path and appends it to // the file in the destination path. -func AppendFile(srcPath string, destFile *os.File) error { +func AppendFile(srcPath string, destFile *os.File) (err error) { srcFile, err := os.Open(srcPath) - err = errorutils.CheckError(err) - if err != nil { - return err + if errorutils.CheckError(err) != nil { + return } - defer func() error { - err := srcFile.Close() - return errorutils.CheckError(err) + defer func() { + e := srcFile.Close() + if err == nil { + err = e + } }() reader := bufio.NewReader(srcFile) @@ -299,7 +303,8 @@ func AppendFile(srcPath string, destFile *os.File) error { writer := bufio.NewWriter(destFile) buf := make([]byte, 1024000) for { - n, err := reader.Read(buf) + var n int + n, err = reader.Read(buf) if err != io.EOF { err = errorutils.CheckError(err) if err != nil { @@ -397,10 +402,20 @@ func GetFileDetailsFromReader(reader io.Reader, includeChecksums bool) (*FileDet details := new(FileDetails) pr, pw := io.Pipe() - defer pr.Close() + defer func() { + e := pr.Close() + if err == nil { + err = errorutils.CheckError(e) + } + }() go func() { - defer pw.Close() + defer func() { + e := pw.Close() + if err == nil { + err = errorutils.CheckError(e) + } + }() details.Size, err = io.Copy(pw, reader) }() @@ -529,8 +544,13 @@ func FindUpstream(itemToFInd string, itemType ItemType) (wd string, exists bool, if err != nil { return } - defer os.Chdir(wd) - + origWd := wd + defer func() { + e := os.Chdir(origWd) + if err == nil { + err = e + } + }() // Get the OS root. osRoot := os.Getenv("SYSTEMDRIVE") if osRoot != "" { @@ -567,7 +587,7 @@ func FindUpstream(itemToFInd string, itemType ItemType) (wd string, exists bool, visitedPaths[wd] = true // CD to the parent directory. wd = filepath.Dir(wd) - err := os.Chdir(wd) + err = os.Chdir(wd) if err != nil { return "", false, err } diff --git a/utils/utils.go b/utils/utils.go index f69e5a71c..b84e6dc40 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -26,7 +26,7 @@ import ( const ( Development = "development" Agent = "jfrog-client-go" - Version = "1.28.0" + Version = "1.28.1" ) // In order to limit the number of items loaded from a reader into the memory, we use a buffers with this size limit. @@ -205,6 +205,7 @@ func cleanPath(path string) string { if io.IsWindows() { // Since filepath.Clean replaces \\ with \, we revert this action. path = strings.ReplaceAll(path, `\`, `\\`) + path = strings.ReplaceAll(path, `\\\\`, `\\`) } return path } @@ -316,10 +317,10 @@ func GetLogMsgPrefix(threadId int, dryRun bool) string { } func TrimPath(path string) string { - path = strings.Replace(path, "\\", "/", -1) - path = strings.Replace(path, "//", "/", -1) - path = strings.Replace(path, "../", "", -1) - path = strings.Replace(path, "./", "", -1) + path = strings.ReplaceAll(path, "\\", "/") + path = strings.ReplaceAll(path, "//", "/") + path = strings.ReplaceAll(path, "../", "") + path = strings.ReplaceAll(path, "./", "") return path } @@ -343,7 +344,7 @@ func GetUserHomeDir() string { if home == "" { home = os.Getenv("USERPROFILE") } - return strings.Replace(home, "\\", "\\\\", -1) + return strings.ReplaceAll(home, "\\", "\\\\") } return os.Getenv("HOME") } diff --git a/xray/services/scan.go b/xray/services/scan.go index 60cb495c5..91f77bb22 100644 --- a/xray/services/scan.go +++ b/xray/services/scan.go @@ -3,6 +3,7 @@ package services import ( "encoding/json" "github.com/jfrog/jfrog-client-go/utils/log" + "golang.org/x/exp/maps" "net/http" "strings" "time" @@ -189,6 +190,25 @@ type GraphNode struct { Parent *GraphNode `json:"-"` } +// FlattenGraph creates a map of dependencies from the given graph, and returns a flat graph of dependencies with one level. +func FlattenGraph(graph []*GraphNode) []*GraphNode { + allDependencies := map[string]*GraphNode{} + for _, node := range graph { + populateUniqueDependencies(node, allDependencies) + } + return []*GraphNode{{Id: "root", Nodes: maps.Values(allDependencies)}} +} + +func populateUniqueDependencies(node *GraphNode, allDependencies map[string]*GraphNode) { + if _, exist := allDependencies[node.Id]; exist { + return + } + allDependencies[node.Id] = &GraphNode{Id: node.Id} + for _, dependency := range node.Nodes { + populateUniqueDependencies(dependency, allDependencies) + } +} + type OtherComponentIds struct { Id string `json:"component_id,omitempty"` Origin int `json:"origin,omitempty"` diff --git a/xray/services/scan_test.go b/xray/services/scan_test.go index 1eafe2a21..9f793460b 100644 --- a/xray/services/scan_test.go +++ b/xray/services/scan_test.go @@ -2,6 +2,8 @@ package services import ( "fmt" + "github.com/jfrog/gofrog/datastructures" + "github.com/stretchr/testify/assert" "testing" ) @@ -47,3 +49,32 @@ func TestCreateScanGraphQueryParams(t *testing.T) { }) } } + +func TestFlattenGraph(t *testing.T) { + nodeA := &GraphNode{Id: "A"} + nodeB := &GraphNode{Id: "B"} + nodeC := &GraphNode{Id: "C"} + nodeD := &GraphNode{Id: "D"} + nodeE := &GraphNode{Id: "E"} + nodeF := &GraphNode{Id: "F"} + + // Set dependencies + nodeA.Nodes = []*GraphNode{nodeB, nodeC} + nodeB.Nodes = []*GraphNode{nodeC, nodeD} + nodeC.Nodes = []*GraphNode{nodeD} + nodeD.Nodes = []*GraphNode{nodeE, nodeF} + nodeF.Nodes = []*GraphNode{nodeA, nodeB, nodeC} + + // Create graph + graph := []*GraphNode{nodeA, nodeB, nodeC} + flatGraph := FlattenGraph(graph) + + // Check that the graph has been flattened correctly + assert.Equal(t, len(flatGraph[0].Nodes), 6) + set := datastructures.MakeSet[string]() + for _, node := range flatGraph[0].Nodes { + assert.Len(t, node.Nodes, 0) + assert.False(t, set.Exists(node.Id)) + set.Add(node.Id) + } +} From 0b22cb3773a5db8107db220b02d1e6301b8c7eda Mon Sep 17 00:00:00 2001 From: Eyal Ben Moshe Date: Thu, 13 Apr 2023 12:48:44 +0300 Subject: [PATCH 02/10] Added the Frogbot badge to the README (#740) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 70f93b276..d07831f42 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ # JFrog Go Client +[![Scanned by Frogbot](https://raw.github.com/jfrog/frogbot/master/images/frogbot-badge.svg)](https://github.com/jfrog/frogbot#readme) + | Branch | Status | From b71c2803fbdf80504f4b4bce0450cb13477db1ea Mon Sep 17 00:00:00 2001 From: yahavi Date: Tue, 23 May 2023 18:44:41 +0300 Subject: [PATCH 03/10] Promoted version to 1.29.1 --- utils/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/utils.go b/utils/utils.go index 7e8932389..1e09afead 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -26,7 +26,7 @@ import ( const ( Development = "development" Agent = "jfrog-client-go" - Version = "1.29.0" + Version = "1.29.1" ) // In order to limit the number of items loaded from a reader into the memory, we use a buffers with this size limit. From f75002534808ee349c90adefcee62b267ee54f9b Mon Sep 17 00:00:00 2001 From: Omer Zidkoni Date: Wed, 12 Jul 2023 14:18:28 +0300 Subject: [PATCH 04/10] Promoted version to 1.31.1 --- utils/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/utils.go b/utils/utils.go index d30dfd5ce..7328edef6 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -26,7 +26,7 @@ import ( const ( Development = "development" Agent = "jfrog-client-go" - Version = "1.31.0" + Version = "1.31.1" ) // In order to limit the number of items loaded from a reader into the memory, we use a buffers with this size limit. From b1ae83639655298e5dd149a0b3d3f7e4c0a3511e Mon Sep 17 00:00:00 2001 From: eyalbe4 Date: Mon, 31 Jul 2023 21:00:52 +0300 Subject: [PATCH 05/10] Promoted version to 1.31.3 --- utils/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/utils.go b/utils/utils.go index 9c1d7246f..654bf095f 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -26,7 +26,7 @@ import ( const ( Development = "development" Agent = "jfrog-client-go" - Version = "1.31.2" + Version = "1.31.3" ) // In order to limit the number of items loaded from a reader into the memory, we use a buffers with this size limit. From 3edc13fe31ecd4c9bc7cfc942c2a5e4c0b09de24 Mon Sep 17 00:00:00 2001 From: eyalbe4 Date: Mon, 18 Dec 2023 17:12:50 +0200 Subject: [PATCH 06/10] Promote to v1.35.2 --- utils/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/utils.go b/utils/utils.go index d464a0bd9..a0ecd4fa7 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -27,7 +27,7 @@ import ( const ( Development = "development" Agent = "jfrog-client-go" - Version = "1.35.1" + Version = "1.35.2" ) type MinVersionProduct string From e249dfe076f500f31d439fe385a3af6b9dd05cbc Mon Sep 17 00:00:00 2001 From: Assaf Attias <49212512+attiasas@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:06:00 +0200 Subject: [PATCH 07/10] Promote version to '1.36.1' (#892) --- utils/utils.go | 2 +- xray/services/scan.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/utils/utils.go b/utils/utils.go index 61a301315..99a9a9a0e 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -27,7 +27,7 @@ import ( const ( Development = "development" Agent = "jfrog-client-go" - Version = "1.36.0" + Version = "1.36.1" ) type MinVersionProduct string diff --git a/xray/services/scan.go b/xray/services/scan.go index 002728554..18f49dc6b 100644 --- a/xray/services/scan.go +++ b/xray/services/scan.go @@ -46,6 +46,8 @@ const ( XscGraphAPI = "api/v1/sca/scan/graph" + multiScanIdParam = "multi_scan_id=" + scanTechQueryParam = "tech=" XscVersionAPI = "api/v1/system/version" @@ -83,6 +85,7 @@ func createScanGraphQueryParams(scanParams XrayGraphScanParams) string { } if scanParams.XscVersion != "" { + params = append(params, multiScanIdParam+scanParams.MultiScanId) gitInfoContext := scanParams.XscGitInfoContext if gitInfoContext != nil { if len(gitInfoContext.Technologies) > 0 { @@ -108,6 +111,7 @@ func (ss *ScanService) ScanGraph(scanParams XrayGraphScanParams) (string, error) if err != nil { return "", fmt.Errorf("failed sending Git Info to XSC service, error: %s ", err.Error()) } + scanParams.MultiScanId = multiScanId if err = os.Setenv("JF_MSI", multiScanId); err != nil { // Not a fatal error, if not set the scan will not be shown at the XSC UI, should not fail the scan. log.Debug(fmt.Sprintf("failed setting MSI as environment variable. Cause: %s", err.Error())) @@ -281,6 +285,7 @@ type XrayGraphScanParams struct { IncludeLicenses bool XscGitInfoContext *XscGitInfoContext XscVersion string + MultiScanId string } type RequestScanResponse struct { From 8b005ae4222a17c989d874dacb602b702c401131 Mon Sep 17 00:00:00 2001 From: Yahav Itzhak Date: Tue, 20 Feb 2024 14:25:36 +0200 Subject: [PATCH 08/10] Merge changes to master (#907) --- README.md | 89 ++++++++++++------- artifactory/services/federatedrepository.go | 12 +++ artifactory/services/fspatterns/utils.go | 3 + artifactory/services/remoterepository.go | 3 +- artifactory/services/upload.go | 27 ++++-- .../services/utils/tests/xray/consts.go | 21 +++++ .../services/utils/tests/xray/server.go | 41 ++++++++- auth/authutils_test.go | 5 +- auth/cert/loader.go | 2 +- go.mod | 22 ++--- go.sum | 43 ++++----- lifecycle/manager.go | 16 ++-- lifecycle/services/create.go | 28 +++--- lifecycle/services/delete.go | 2 +- lifecycle/services/operation.go | 13 +-- lifecycle/services/promote.go | 34 ++++--- pipelines/manager.go | 6 ++ pipelines/services/integration.go | 16 +++- tests/artifactoryfederatedrepository_test.go | 22 +++++ tests/artifactorylocalrepository_test.go | 22 +++++ tests/artifactoryremoterepository_test.go | 28 +++--- tests/artifactoryvirtualrepository_test.go | 22 ++--- tests/pipelinesintegrations_test.go | 26 ++++++ tests/xray_test.go | 4 +- tests/xrayreport_test.go | 2 +- tests/xrayscan_test.go | 62 ++++++++++++- tests/xraysummary_test.go | 2 +- utils/utils.go | 2 +- xray/manager.go | 7 ++ xray/services/scan.go | 32 ++----- 30 files changed, 442 insertions(+), 172 deletions(-) diff --git a/README.md b/README.md index 2a4f3ac9c..4e761e7e3 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,9 @@ - [Delete Violations Report](#delete-violations-report) - [Get Artifact Summary](#get-artifact-summary) - [Get Entitlement info](#get-entitlement-info) + - [Using XSC Service](#using-xsc-service) + - [Check if xsc is enabled](#check-if-xsc-is-enabled) + - [Send git info details to xsc](#send-git-info-details-to-xsc) - [Pipelines APIs](#pipelines-apis) - [Creating Pipelines Service Manager](#creating-pipelines-service-manager) - [Creating Pipelines Details](#creating-pipelines-details) @@ -185,6 +188,7 @@ - [Get Integration by Id](#get-integration-by-id) - [Get Integration by Name](#get-integration-by-name) - [Get All Integrations](#get-all-integrations) + - [Get All Raw Integrations](#get-all-raw-integrations) - [Delete Integration](#delete-integration) - [Add Pipeline Source](#add-pipeline-source) - [Get Recent Pipeline Run Status](#get-recent-pipeline-run-status) @@ -802,7 +806,7 @@ apiKey, err := rtManager.GetAPIKey() You can create and update a local repository for the following package types: Alpine, Bower, Cran, Cargo, Chef, Cocoapods, Composer, Conan, Conda, Debian, Docker, Gems, Generic, Gitlfs, Go, Gradle, -Helm, Ivy, Maven, Npm, Nuget, Opkg, Puppet, Pypi, Rpm, Sbt, Swift, Vagrant, and Yum. +Helm, Ivy, Maven, Npm, Nuget, Opkg, Puppet, Pypi, Rpm, Sbt, Swift, Terraform, Vagrant, and Yum. Each package type has its own parameters struct, can be created using the method `NewLocalRepositoryParams()`. @@ -845,7 +849,7 @@ err = servicesManager.UpdateLocalRepository().Generic(params) You can create and update a remote repository for the following package types: Alpine, Bower, Cran, Cargo, Chef, Cocoapods, Composer, Conan, Conda, Debian, Docker, Gems, Generic, Gitlfs, Go, Gradle, -Helm, Ivy, Maven, Npm, Nuget, Opkg, P2, Puppet, Pypi, Rpm, Sbt, Swift, Vcs, and Yum. +Helm, Ivy, Maven, Npm, Nuget, Opkg, P2, Puppet, Pypi, Rpm, Sbt, Swift, Terraform, Vcs, and Yum. Each package type has its own parameters struct, can be created using the method `NewRemoteRepositoryParams()`. @@ -889,7 +893,7 @@ err := servicesManager.CreateRemoteRepository(params) You can create and update a virtual repository for the following package types: Alpine, Bower, Cran, Chef, Conan, Conda, Debian, Docker, Gems, Generic, Gitlfs, Go, Gradle, Helm, Ivy, Maven, Npm, -Nuget, P2, Puppet, Pypi, Rpm, Sbt, Swift and Yum. +Nuget, P2, Puppet, Pypi, Rpm, Sbt, Swift, Terraform and Yum. Each package type has its own parameters struct, can be created using the method `NewVirtualRepositoryParams()`. @@ -931,7 +935,7 @@ err = servicesManager.UpdateVirtualRepository().Go(params) You can create and update a federated repository for the following package types: Alpine, Bower, Cran, Cargo, Chef, Cocoapods, Composer, Conan, Conda, Debian, Docker, Gems, Generic, Gitlfs, Go, Gradle, -Helm, Ivy, Maven, Npm, Nuget, Opkg, Puppet, Pypi, Rpm, Sbt, Swift Vagrant and Yum +Helm, Ivy, Maven, Npm, Nuget, Opkg, Puppet, Pypi, Rpm, Sbt, Swift, Terraform, Vagrant and Yum Each package type has its own parameters struct, can be created using the method `NewFederatedRepositoryParams()`. @@ -2210,6 +2214,23 @@ artifactSummary, err := xrayManager.ArtifactSummary(artifactSummaryRequest) isEntitled, err := xrayManager.IsEntitled(featureId) ``` +### Using XSC Service + +#### Check if xsc is enabled + +```go +// Will try to get XSC version. If route is not available, user is not entitled for XSC. +xscVersion, err := scanService.IsXscEnabled() +``` + +#### Send git info details to xsc + +```go +// Details are the git info details (gitRepoUrl, branchName, commitHash are required fields). Returns multi scan id. +multiScanId, err := scanService.SendScanGitInfoContext(details) +``` + + ## Pipelines APIs ### Creating Pipelines Service Manager @@ -2305,6 +2326,12 @@ integration, err := pipelinesManager.GetIntegrationByName("integrationName") integrations, err := pipelinesManager.GetAllIntegrations() ``` +#### Get All Raw Integrations + +```go +integrations, err := pipelinesManager.GetAllRawIntegrations() +``` + #### Delete Integration ```go @@ -2396,13 +2423,12 @@ lifecycleManager, err := lifecycle.New(serviceConfig) ```go rbDetails := ReleaseBundleDetails{"rbName", "rbVersion"} -params := CreateOrPromoteReleaseBundleParams{} -// The GPG/RSA key-pair name given in Artifactory. -params.SigningKeyName = "key-pair" -// Optional: -params.ProjectKey = "project" -params.Async = true +queryParams := CommonOptionalQueryParams{} +queryParams.ProjectKey = "project" +queryParams.Async = true +// The GPG/RSA key-pair name given in Artifactory. +signingKeyName = "key-pair" source := CreateFromBuildsSource{Builds: []BuildSource{ { @@ -2412,19 +2438,19 @@ source := CreateFromBuildsSource{Builds: []BuildSource{ BuildRepository: "artifactory-build-info", }, }} -serviceManager.CreateReleaseBundleFromBuilds(rbDetails, params, source) +serviceManager.CreateReleaseBundleFromBuilds(rbDetails, queryParams, signingKeyName, source) ``` #### Creating a Release Bundle From Release Bundles ```go rbDetails := ReleaseBundleDetails{"rbName", "rbVersion"} -params := CreateOrPromoteReleaseBundleParams{} +queryParams := CommonOptionalQueryParams{} +queryParams.ProjectKey = "project" +queryParams.Async = true + // The GPG/RSA key-pair name given in Artifactory. -params.SigningKeyName = "key-pair" -// Optional: -params.ProjectKey = "project" -params.Async = true +signingKeyName = "key-pair" source := CreateFromReleaseBundlesSource{ReleaseBundles: []ReleaseBundleSource{ { @@ -2433,23 +2459,25 @@ source := CreateFromReleaseBundlesSource{ReleaseBundles: []ReleaseBundleSource{ ProjectKey: "default", }, }} -serviceManager.CreateReleaseBundleFromBundles(rbDetails, params, source) +serviceManager.CreateReleaseBundleFromBundles(rbDetails, params, signingKeyName, source) ``` #### Promoting a Release Bundle ```go rbDetails := ReleaseBundleDetails{"rbName", "rbVersion"} -params := CreateOrPromoteReleaseBundleParams{} +queryParams := CommonOptionalQueryParams{} +queryParams.ProjectKey = "project" +queryParams.Async = true + // The GPG/RSA key-pair name given in Artifactory. -params.SigningKeyName = "key-pair" -// Optional: -params.ProjectKey = "project" -params.Async = true +signingKeyName = "key-pair" -environment := "target-env" -overwrite:=true -resp, err := serviceManager.PromoteReleaseBundle(rbDetails, params, environment, overwrite) +promotionParams := RbPromotionParams{} +promotionParams.Environment := "target-env" +promotionParams.IncludedRepositoryKeys := []string{"generic-local"} + +resp, err := serviceManager.PromoteReleaseBundle(rbDetails, queryParams, signingKeyName, promotionParams) ``` #### Get Release Bundle Creation Status @@ -2498,14 +2526,11 @@ resp, err := serviceManager.DistributeReleaseBundle(params, autoCreateRepo, path ```go rbDetails := ReleaseBundleDetails{"rbName", "rbVersion"} -params := CreateOrPromoteReleaseBundleParams{} -// The GPG/RSA key-pair name given in Artifactory. -params.SigningKeyName = "key-pair" -// Optional: -params.ProjectKey = "project" -params.Async = true +queryParams := CommonOptionalQueryParams{} +queryParams.ProjectKey = "project" +queryParams.Async = true -resp, err := serviceManager.DeleteReleaseBundle(rbDetails, params) +resp, err := serviceManager.DeleteReleaseBundle(rbDetails, queryParams) ``` #### Remote Delete Release Bundle diff --git a/artifactory/services/federatedrepository.go b/artifactory/services/federatedrepository.go index 6e6e2bedc..93fafe410 100644 --- a/artifactory/services/federatedrepository.go +++ b/artifactory/services/federatedrepository.go @@ -135,6 +135,10 @@ func (frs *FederatedRepositoryService) Swift(params SwiftFederatedRepositoryPara return frs.performRequest(params, params.Key) } +func (frs *FederatedRepositoryService) Terraform(params TerraformFederatedRepositoryParams) error { + return frs.performRequest(params, params.Key) +} + func (frs *FederatedRepositoryService) Vagrant(params VagrantFederatedRepositoryParams) error { return frs.performRequest(params, params.Key) } @@ -389,6 +393,14 @@ func NewSwiftFederatedRepositoryParams() SwiftFederatedRepositoryParams { return SwiftFederatedRepositoryParams{FederatedRepositoryBaseParams: NewFederatedRepositoryPackageParams("swift")} } +type TerraformFederatedRepositoryParams struct { + FederatedRepositoryBaseParams +} + +func NewTerraformFederatedRepositoryParams() TerraformFederatedRepositoryParams { + return TerraformFederatedRepositoryParams{FederatedRepositoryBaseParams: NewFederatedRepositoryPackageParams("terraform")} +} + type VagrantFederatedRepositoryParams struct { FederatedRepositoryBaseParams } diff --git a/artifactory/services/fspatterns/utils.go b/artifactory/services/fspatterns/utils.go index f6bbd6773..5cfc3d578 100644 --- a/artifactory/services/fspatterns/utils.go +++ b/artifactory/services/fspatterns/utils.go @@ -125,6 +125,9 @@ func isPathExcluded(path string, excludePathPattern string) (excludedPath bool, // If filePath is path to a symlink we should return the link content e.g where the link points func GetFileSymlinkPath(filePath string) (string, error) { + if filePath == "" { + return "", nil + } fileInfo, e := os.Lstat(filePath) if errorutils.CheckError(e) != nil { return "", e diff --git a/artifactory/services/remoterepository.go b/artifactory/services/remoterepository.go index cd50c7559..f675af3d4 100644 --- a/artifactory/services/remoterepository.go +++ b/artifactory/services/remoterepository.go @@ -481,10 +481,9 @@ func NewSwiftRemoteRepositoryParams() SwiftRemoteRepositoryParams { type TerraformRemoteRepositoryParams struct { RemoteRepositoryBaseParams + VcsGitRemoteRepositoryParams TerraformRegistryUrl string `json:"terraformRegistryUrl,omitempty"` TerraformProvidersUrl string `json:"terraformProvidersUrl,omitempty"` - VcsType string `json:"vcsType,omitempty"` - VcsGitProvider string `json:"vcsGitProvider,omitempty"` } func NewTerraformRemoteRepositoryParams() TerraformRemoteRepositoryParams { diff --git a/artifactory/services/upload.go b/artifactory/services/upload.go index d2bb290cd..6ac6a81c7 100644 --- a/artifactory/services/upload.go +++ b/artifactory/services/upload.go @@ -40,6 +40,8 @@ type UploadService struct { resultsManager *resultsManager } +const JfrogCliUploadEmptyArchiveEnv = "JFROG_CLI_UPLOAD_EMPTY_ARCHIVE" + func NewUploadService(client *jfroghttpclient.JfrogHttpClient) *UploadService { return &UploadService{client: client} } @@ -317,10 +319,17 @@ func scanFilesByPattern(uploadParams UploadParams, rootPath string, progressMgr } // Longest files path first sort.Sort(sort.Reverse(sort.StringSlice(paths))) - var uploadedTargets []string + // 'uploadedDirs' is in use only when we need to upload folders with flat=true. // 'uploadedDirs' will contain only local directories paths that have been uploaded to Artifactory. - var uploadedDirs []string + var uploadedTargets, uploadedDirs []string + + if shouldUploadAnEmptyArchive(uploadParams.Archive, paths) { + log.Info("All files were filtered out by the exclusion pattern, but the archive flag is set together with JFROG_CLI_UPLOAD_EMPTY_ARCHIVE environment variable. " + + "Proceeding with an empty archive.") + paths = []string{""} + } + for _, path := range paths { matches, isDir, err := fspatterns.SearchPatterns(path, uploadParams.IsSymlink(), uploadParams.IsIncludeDirs(), patternRegex) if err != nil { @@ -350,6 +359,12 @@ func scanFilesByPattern(uploadParams UploadParams, rootPath string, progressMgr return nil } +func shouldUploadAnEmptyArchive(archive string, paths []string) bool { + return len(paths) == 0 && + archive != "" && + strings.ToLower(os.Getenv(JfrogCliUploadEmptyArchiveEnv)) == "true" +} + // targetFiles - Paths in Artifactory of the files that were uploaded. // sourceDirs - Paths of the local dirs that have already been uploaded to Artifactory. (Longest files path first). // targetDir - The directory target path to be uploaded. @@ -834,9 +849,11 @@ func (us *UploadService) readFilesAsZip(archiveDataReader *content.ContentReader } }() for uploadData := new(UploadData); archiveDataReader.NextRecord(uploadData) == nil; uploadData = new(UploadData) { - e = us.addFileToZip(&uploadData.Artifact, progressPrefix, flat, symlink, zipWriter) - if e != nil { - errorsQueue.AddError(e) + if uploadData.Artifact.LocalPath != "" { + e = us.addFileToZip(&uploadData.Artifact, progressPrefix, flat, symlink, zipWriter) + if e != nil { + errorsQueue.AddError(e) + } } if saveFilesPathsFunc != nil { e = saveFilesPathsFunc(uploadData.Artifact.LocalPath) diff --git a/artifactory/services/utils/tests/xray/consts.go b/artifactory/services/utils/tests/xray/consts.go index e8992eb57..66146282f 100644 --- a/artifactory/services/utils/tests/xray/consts.go +++ b/artifactory/services/utils/tests/xray/consts.go @@ -1,5 +1,7 @@ package xray +import xrayServices "github.com/jfrog/jfrog-client-go/xray/services" + const FatalErrorXrayScanResponse = ` { "errors": [{"status":-1}, {"status":500}] @@ -1414,6 +1416,25 @@ const BuildScanResultsResponse = ` ] } ` +const xscVersionResponse = `{"xsc_version": "1.0.0"}` + +const XscGitInfoResponse = `{"multi_scan_id": "3472b4e2-bddc-11ee-a9c9-acde48001122"}` + +const XscGitInfoBadResponse = `"failed create git info request: git_repo_url field must contain value"` + +var GitInfoContextWithMinimalRequiredFields = xrayServices.XscGitInfoContext{ + GitRepoUrl: "https://git.jfrog.info/projects/XSC/repos/xsc-service", + BranchName: "feature/XRAY-123-cool-feature", + CommitHash: "acc5e24e69a-d3c1-4022-62eb-69e4a1e5", +} + +var GitInfoContextWithMissingFields = xrayServices.XscGitInfoContext{ + GitRepoUrl: "https://git.jfrog.info/projects/XSC/repos/xsc-service", + BranchName: "feature/XRAY-123-cool-feature", +} + +const TestMultiScanId = "3472b4e2-bddc-11ee-a9c9-acde48001122" +const TestXscVersion = "1.0.0" var MapReportIdEndpoint = map[int]string{ 777: VulnerabilitiesEndpoint, diff --git a/artifactory/services/utils/tests/xray/server.go b/artifactory/services/utils/tests/xray/server.go index 12abe70bf..79a4aa724 100644 --- a/artifactory/services/utils/tests/xray/server.go +++ b/artifactory/services/utils/tests/xray/server.go @@ -1,17 +1,20 @@ package xray import ( + "encoding/json" "fmt" "io" "net/http" "os" "strconv" "strings" + "testing" "github.com/buger/jsonparser" "github.com/jfrog/jfrog-client-go/utils/log" clienttests "github.com/jfrog/jfrog-client-go/utils/tests" "github.com/jfrog/jfrog-client-go/xray/services" + "github.com/stretchr/testify/assert" ) const ( @@ -183,11 +186,47 @@ func buildScanHandler(w http.ResponseWriter, r *http.Request) { http.Error(w, "Invalid reports request", http.StatusBadRequest) } -func StartXrayMockServer() int { +func xscGetVersionHandlerFunc(t *testing.T) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodGet { + _, err := fmt.Fprint(w, xscVersionResponse) + assert.NoError(t, err) + return + } + http.Error(w, "Invalid xsc request", http.StatusBadRequest) + } +} + +func xscGitInfoHandlerFunc(t *testing.T) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + req, err := io.ReadAll(r.Body) + assert.NoError(t, err) + if r.Method == http.MethodPost { + var reqBody services.XscGitInfoContext + err = json.Unmarshal(req, &reqBody) + assert.NoError(t, err) + if reqBody.GitRepoUrl == "" || reqBody.BranchName == "" || reqBody.CommitHash == "" { + w.WriteHeader(http.StatusBadRequest) + _, err := fmt.Fprint(w, XscGitInfoBadResponse) + assert.NoError(t, err) + return + } + w.WriteHeader(http.StatusCreated) + _, err = fmt.Fprint(w, XscGitInfoResponse) + assert.NoError(t, err) + return + } + http.Error(w, "Invalid xsc request", http.StatusBadRequest) + } +} + +func StartXrayMockServer(t *testing.T) int { handlers := clienttests.HttpServerHandlers{} handlers["/api/xray/scanBuild"] = scanBuildHandler handlers["/api/v2/summary/artifact"] = artifactSummaryHandler handlers["/api/v1/entitlements/feature/"] = entitlementsHandler + handlers["/xsc/api/v1/system/version"] = xscGetVersionHandlerFunc(t) + handlers["/xsc/api/v1/gitinfo"] = xscGitInfoHandlerFunc(t) handlers[fmt.Sprintf("/%s/", services.ReportsAPI)] = reportHandler handlers[fmt.Sprintf("/%s/", services.BuildScanAPI)] = buildScanHandler handlers["/"] = http.NotFound diff --git a/auth/authutils_test.go b/auth/authutils_test.go index 0e2f04d5d..570396ef3 100644 --- a/auth/authutils_test.go +++ b/auth/authutils_test.go @@ -6,11 +6,14 @@ import ( "github.com/stretchr/testify/assert" ) -/* #nosec G101 -- Dummy tokens for tests. */ var ( + // #nosec G101 -- Dummy tokens for tests token1 = "eyJ2ZXIiOiIyIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYiLCJraWQiOiJIcnU2VHctZk1yOTV3dy12TDNjV3ZBVjJ3Qm9FSHpHdGlwUEFwOE1JdDljIn0.eyJzdWIiOiJqZnJ0QDAxYzNnZmZoZzJlOHc2MTQ5ZTNhMnEwdzk3XC91c2Vyc1wvYWRtaW4iLCJzY3AiOiJtZW1iZXItb2YtZ3JvdXBzOnJlYWRlcnMgYXBpOioiLCJhdWQiOiJqZnJ0QDAxYzNnZmZoZzJlOHc2MTQ5ZTNhMnEwdzk3IiwiaXNzIjoiamZydEAwMWMzZ2ZmaGcyZTh3NjE0OWUzYTJxMHc5NyIsImV4cCI6MTU1NjAzNzc2NSwiaWF0IjoxNTU2MDM0MTY1LCJqdGkiOiI1M2FlMzgyMy05NGM3LTQ0OGItOGExOC1iZGVhNDBiZjFlMjAifQ.Bp3sdvppvRxysMlLgqT48nRIHXISj9sJUCXrm7pp8evJGZW1S9hFuK1olPmcSybk2HNzdzoMcwhUmdUzAssiQkQvqd_HanRcfFbrHeg5l1fUQ397ECES-r5xK18SYtG1VR7LNTVzhJqkmRd3jzqfmIK2hKWpEgPfm8DRz3j4GGtDRxhb3oaVsT2tSSi_VfT3Ry74tzmO0GcCvmBE2oh58kUZ4QfEsalgZ8IpYHTxovsgDx_M7ujOSZx_hzpz-iy268-OkrU22PQPCfBmlbEKeEUStUO9n0pj4l1ODL31AGARyJRy46w4yzhw7Fk5P336WmDMXYs5LAX2XxPFNLvNzA" + // #nosec G101 token2 = "eyJ2ZXIiOiIyIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYiLCJraWQiOiJIcnU2VHctZk1yOTV3dy12TDNjV3ZBVjJ3Qm9FSHpHdGlwUEFwOE1JdDljIn0.eyJzdWIiOiJqZnJ0QDAwMWMzZ2ZmaGcyZTh3NjE0OWUzYTJxMHc5NyIsImV4cCI6MTU1NjAzNzc2NSwiaWF0IjoxNTU2MDM0MTY1LCJqdGkiOiI1M2FlMzgyMy05NGM3LTQ0OGItOGExOC1iZGVhNDBiZjFlMjAifQ.Bp3sdvppvRxysMlLgqT48nRIHXISj9sJUCXrm7pp8evJGZW1S9hFuK1olPmcSybk2HNzdzoMcwhUmdUzAssiQkQvqd_HanRcfFbrHeg5l1fUQ397ECES-r5xK18SYtG1VR7LNTVzhJqkmRd3jzqfmIK2hKWpEgPfm8DRz3j4GGtDRxhb3oaVsT2tSSi_VfT3Ry74tzmO0GcCvmBE2oh58kUZ4QfEsalgZ8IpYHTxovsgDx_M7ujOSZx_hzpz-iy268-OkrU22PQPCfBmlbEKeEUStUO9n0pj4l1ODL31AGARyJRy46w4yzhw7Fk5P336WmDMXYs5LAX2XxPFNLvNzA" + // #nosec G101 token3 = "eyJ2ZXIiOiIyIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYiLCJraWQiOiJIcnU2VHctZk1yOTV3dy12TDNjV3ZBVjJ3Qm9FSHpHdGlwUEFwOE1JdDljIn0" + // #nosec G101 token4 = "eyJ2ZXIiOiIyIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYiLCJraWQiOiJsS0NYXzFvaTBQbTZGdF9XRklkejZLZ1g4U0FULUdOY0lJWXRjTC1KM084In0.eyJzdWIiOiJqZmZlQDAwMFwvdXNlcnNcL3RlbXB1c2VyIiwic2NwIjoiYXBwbGllZC1wZXJtaXNzaW9uc1wvYWRtaW4gYXBpOioiLCJhdWQiOlsiamZydEAqIiwiamZtZEAqIiwiamZldnRAKiIsImpmYWNAKiJdLCJpc3MiOiJqZmZlQDAwMCIsImV4cCI6MTYxNjQ4OTU4NSwiaWF0IjoxNjE2NDg1OTg1LCJqdGkiOiI0OTBlYWEzOS1mMzYxLTQxYjAtOTA5Ni1kNjg5NmQ0ZWQ3YjEifQ.J5P8Pu5tqEjgnLFLEoCdh1LJHWiMmEHht95v0EFuixwO-osq7sfXua_UCGBkKbmqVSGKew9kl_LTcbq_uMe281_5q2yYxT74iqc2wQ1K0uovEUeIU6E65oi70JwUWUwcF3sNJ2gFatnvgSu-2Kv6m-DtSIW36WS3Mh8uMZQ19ob4fmueVmMFyQsp0EEG6xFYeOK6SB8OUd0gAd_XvXiSRuF0eLabhKmXM2pVBLYfd2KIMlkFckEOGGOzeglvA62xmP4Ik7UsF487NAo0LeS_Pd79owr0jtgTYkCTrLlFhUzUMDVmD_LsCMyf_S4CJxhwkCRhhy9SYSs1WPgknL3--w" ) diff --git a/auth/cert/loader.go b/auth/cert/loader.go index b8afcd915..1c1d50cfa 100644 --- a/auth/cert/loader.go +++ b/auth/cert/loader.go @@ -54,10 +54,10 @@ func GetTransportWithLoadedCert(certificatesDirPath string, insecureTls bool, tr if err != nil { return nil, err } - //#nosec G402 -- Skipping insecure tls verification was requested by the user. transport.TLSClientConfig = &tls.Config{ RootCAs: caCertPool, ClientSessionCache: tls.NewLRUClientSessionCache(1), + //#nosec G402 -- Skipping insecure tls verification was requested by the user. InsecureSkipVerify: insecureTls, } diff --git a/go.mod b/go.mod index a91f4dd73..ee4795321 100644 --- a/go.mod +++ b/go.mod @@ -10,21 +10,21 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.0 github.com/gookit/color v1.5.4 github.com/jfrog/archiver/v3 v3.6.0 - github.com/jfrog/build-info-go v1.9.21 - github.com/jfrog/gofrog v1.5.1 + github.com/jfrog/build-info-go v1.9.22 + github.com/jfrog/gofrog v1.6.0 github.com/stretchr/testify v1.8.4 github.com/xanzy/ssh-agent v0.3.3 - golang.org/x/crypto v0.18.0 - golang.org/x/exp v0.0.0-20240119083558-1b970713d09a - golang.org/x/term v0.16.0 + golang.org/x/crypto v0.19.0 + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a + golang.org/x/term v0.17.0 ) require ( dario.cat/mergo v1.0.0 // indirect - github.com/CycloneDX/cyclonedx-go v0.7.2 // indirect + github.com/CycloneDX/cyclonedx-go v0.8.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/andybalholm/brotli v1.1.0 // indirect - github.com/cloudflare/circl v1.3.3 // indirect + github.com/cloudflare/circl v1.3.7 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dsnet/compress v0.0.1 // indirect @@ -49,10 +49,10 @@ require ( github.com/ulikunitz/xz v0.5.11 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/tools v0.18.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d6cd47349..a509260fe 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/CycloneDX/cyclonedx-go v0.7.2 h1:kKQ0t1dPOlugSIYVOMiMtFqeXI2wp/f5DBIdfux8gnQ= -github.com/CycloneDX/cyclonedx-go v0.7.2/go.mod h1:K2bA+324+Og0X84fA8HhN2X066K7Bxz4rpMQ4ZhjtSk= +github.com/CycloneDX/cyclonedx-go v0.8.0 h1:FyWVj6x6hoJrui5uRQdYZcSievw3Z32Z88uYzG/0D6M= +github.com/CycloneDX/cyclonedx-go v0.8.0/go.mod h1:K2bA+324+Og0X84fA8HhN2X066K7Bxz4rpMQ4ZhjtSk= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= @@ -15,8 +15,9 @@ github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oM github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -51,10 +52,10 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jfrog/archiver/v3 v3.6.0 h1:OVZ50vudkIQmKMgA8mmFF9S0gA47lcag22N13iV3F1w= github.com/jfrog/archiver/v3 v3.6.0/go.mod h1:fCAof46C3rAXgZurS8kNRNdSVMKBbZs+bNNhPYxLldI= -github.com/jfrog/build-info-go v1.9.21 h1:bcD0SEC2lEilhjE+aDB3xlvA8zsr4Kw/bFzvr9Tcj9I= -github.com/jfrog/build-info-go v1.9.21/go.mod h1:Vxv6zmx4e1NWsx40OHaDWCCYDeYAq2yXzpJ4nsDChbE= -github.com/jfrog/gofrog v1.5.1 h1:2AXL8hHu1jJFMIoCqTp2OyRUfEqEp4nC7J8fwn6KtwE= -github.com/jfrog/gofrog v1.5.1/go.mod h1:SZ1EPJUruxrVGndOzHd+LTiwWYKMlHqhKD+eu+v5Hqg= +github.com/jfrog/build-info-go v1.9.22 h1:+RPM8OJvgBvOo+PYPnVYkg+S3hl1JlyCJn/aGxLqRMI= +github.com/jfrog/build-info-go v1.9.22/go.mod h1:QHcKuesY4MrBVBuEwwBz4uIsX6mwYuMEDV09ng4AvAU= +github.com/jfrog/gofrog v1.6.0 h1:jOwb37nHY2PnxePNFJ6e6279Pgkr3di05SbQQw47Mq8= +github.com/jfrog/gofrog v1.6.0/go.mod h1:SZ1EPJUruxrVGndOzHd+LTiwWYKMlHqhKD+eu+v5Hqg= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= @@ -115,14 +116,14 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -130,8 +131,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -150,15 +151,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -171,8 +172,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/lifecycle/manager.go b/lifecycle/manager.go index e08ea15cc..f8911bb68 100644 --- a/lifecycle/manager.go +++ b/lifecycle/manager.go @@ -37,20 +37,20 @@ func (lcs *LifecycleServicesManager) Client() *jfroghttpclient.JfrogHttpClient { } func (lcs *LifecycleServicesManager) CreateReleaseBundleFromBuilds(rbDetails lifecycle.ReleaseBundleDetails, - params lifecycle.CreateOrPromoteReleaseBundleParams, sourceBuilds lifecycle.CreateFromBuildsSource) error { + queryParams lifecycle.CommonOptionalQueryParams, signingKeyName string, sourceBuilds lifecycle.CreateFromBuildsSource) error { rbService := lifecycle.NewReleaseBundlesService(lcs.config.GetServiceDetails(), lcs.client) - return rbService.CreateFromBuilds(rbDetails, params, sourceBuilds) + return rbService.CreateFromBuilds(rbDetails, queryParams, signingKeyName, sourceBuilds) } func (lcs *LifecycleServicesManager) CreateReleaseBundleFromBundles(rbDetails lifecycle.ReleaseBundleDetails, - params lifecycle.CreateOrPromoteReleaseBundleParams, sourceReleaseBundles lifecycle.CreateFromReleaseBundlesSource) error { + queryParams lifecycle.CommonOptionalQueryParams, signingKeyName string, sourceReleaseBundles lifecycle.CreateFromReleaseBundlesSource) error { rbService := lifecycle.NewReleaseBundlesService(lcs.config.GetServiceDetails(), lcs.client) - return rbService.CreateFromBundles(rbDetails, params, sourceReleaseBundles) + return rbService.CreateFromBundles(rbDetails, queryParams, signingKeyName, sourceReleaseBundles) } -func (lcs *LifecycleServicesManager) PromoteReleaseBundle(rbDetails lifecycle.ReleaseBundleDetails, params lifecycle.CreateOrPromoteReleaseBundleParams, environment string, overwrite bool) (lifecycle.RbPromotionResp, error) { +func (lcs *LifecycleServicesManager) PromoteReleaseBundle(rbDetails lifecycle.ReleaseBundleDetails, queryParams lifecycle.CommonOptionalQueryParams, signingKeyName string, promotionParams lifecycle.RbPromotionParams) (lifecycle.RbPromotionResp, error) { rbService := lifecycle.NewReleaseBundlesService(lcs.config.GetServiceDetails(), lcs.client) - return rbService.Promote(rbDetails, params, environment, overwrite) + return rbService.Promote(rbDetails, queryParams, signingKeyName, promotionParams) } func (lcs *LifecycleServicesManager) GetReleaseBundleCreationStatus(rbDetails lifecycle.ReleaseBundleDetails, projectKey string, sync bool) (lifecycle.ReleaseBundleStatusResponse, error) { @@ -63,9 +63,9 @@ func (lcs *LifecycleServicesManager) GetReleaseBundlePromotionStatus(rbDetails l return rbService.GetReleaseBundlePromotionStatus(rbDetails, projectKey, createdMillis, sync) } -func (lcs *LifecycleServicesManager) DeleteReleaseBundle(rbDetails lifecycle.ReleaseBundleDetails, params lifecycle.ReleaseBundleQueryParams) error { +func (lcs *LifecycleServicesManager) DeleteReleaseBundle(rbDetails lifecycle.ReleaseBundleDetails, queryParams lifecycle.CommonOptionalQueryParams) error { rbService := lifecycle.NewReleaseBundlesService(lcs.config.GetServiceDetails(), lcs.client) - return rbService.DeleteReleaseBundle(rbDetails, params) + return rbService.DeleteReleaseBundle(rbDetails, queryParams) } func (lcs *LifecycleServicesManager) DistributeReleaseBundle(params distribution.DistributionParams, autoCreateRepo bool, pathMapping lifecycle.PathMapping) error { diff --git a/lifecycle/services/create.go b/lifecycle/services/create.go index bb3152188..a095a5e40 100644 --- a/lifecycle/services/create.go +++ b/lifecycle/services/create.go @@ -12,8 +12,9 @@ const ( ) type createOperation struct { - reqBody RbCreationBody - params CreateOrPromoteReleaseBundleParams + reqBody RbCreationBody + params CommonOptionalQueryParams + signingKeyName string } func (c *createOperation) getOperationRestApi() string { @@ -28,29 +29,35 @@ func (c *createOperation) getOperationSuccessfulMsg() string { return "Release Bundle successfully created" } -func (c *createOperation) getOperationParams() CreateOrPromoteReleaseBundleParams { +func (c *createOperation) getOperationParams() CommonOptionalQueryParams { return c.params } -func (rbs *ReleaseBundlesService) CreateFromBuilds(rbDetails ReleaseBundleDetails, params CreateOrPromoteReleaseBundleParams, sourceBuilds CreateFromBuildsSource) error { +func (c *createOperation) getSigningKeyName() string { + return c.signingKeyName +} + +func (rbs *ReleaseBundlesService) CreateFromBuilds(rbDetails ReleaseBundleDetails, params CommonOptionalQueryParams, signingKeyName string, sourceBuilds CreateFromBuildsSource) error { operation := createOperation{ reqBody: RbCreationBody{ ReleaseBundleDetails: rbDetails, SourceType: builds, Source: sourceBuilds}, - params: params, + params: params, + signingKeyName: signingKeyName, } _, err := rbs.doOperation(&operation) return err } -func (rbs *ReleaseBundlesService) CreateFromBundles(rbDetails ReleaseBundleDetails, params CreateOrPromoteReleaseBundleParams, sourceReleaseBundles CreateFromReleaseBundlesSource) error { +func (rbs *ReleaseBundlesService) CreateFromBundles(rbDetails ReleaseBundleDetails, params CommonOptionalQueryParams, signingKeyName string, sourceReleaseBundles CreateFromReleaseBundlesSource) error { operation := createOperation{ reqBody: RbCreationBody{ ReleaseBundleDetails: rbDetails, SourceType: releaseBundles, Source: sourceReleaseBundles}, - params: params, + params: params, + signingKeyName: signingKeyName, } _, err := rbs.doOperation(&operation) return err @@ -67,9 +74,10 @@ type CreateFromBuildsSource struct { } type BuildSource struct { - BuildName string `json:"build_name,omitempty"` - BuildNumber string `json:"build_number,omitempty"` - BuildRepository string `json:"build_repository,omitempty"` + BuildName string `json:"build_name,omitempty"` + BuildNumber string `json:"build_number,omitempty"` + BuildRepository string `json:"build_repository,omitempty"` + IncludeDependencies bool `json:"include_dependencies,omitempty"` } type CreateFromReleaseBundlesSource struct { diff --git a/lifecycle/services/delete.go b/lifecycle/services/delete.go index 61e8b4260..9834be00f 100644 --- a/lifecycle/services/delete.go +++ b/lifecycle/services/delete.go @@ -15,7 +15,7 @@ const ( remoteDeleteEndpoint = "remote_delete" ) -func (rbs *ReleaseBundlesService) DeleteReleaseBundle(rbDetails ReleaseBundleDetails, params ReleaseBundleQueryParams) error { +func (rbs *ReleaseBundlesService) DeleteReleaseBundle(rbDetails ReleaseBundleDetails, params CommonOptionalQueryParams) error { queryParams := getProjectQueryParam(params.ProjectKey) queryParams[async] = strconv.FormatBool(params.Async) restApi := path.Join(releaseBundleBaseApi, records, rbDetails.ReleaseBundleName, rbDetails.ReleaseBundleVersion) diff --git a/lifecycle/services/operation.go b/lifecycle/services/operation.go index 3d44f6db6..cb97ff35b 100644 --- a/lifecycle/services/operation.go +++ b/lifecycle/services/operation.go @@ -31,7 +31,8 @@ type ReleaseBundleOperation interface { getOperationRestApi() string getRequestBody() any getOperationSuccessfulMsg() string - getOperationParams() CreateOrPromoteReleaseBundleParams + getOperationParams() CommonOptionalQueryParams + getSigningKeyName() string } func (rbs *ReleaseBundlesService) doOperation(operation ReleaseBundleOperation) ([]byte, error) { @@ -43,7 +44,7 @@ func (rbs *ReleaseBundlesService) doOperation(operation ReleaseBundleOperation) } httpClientDetails := rbs.GetLifecycleDetails().CreateHttpClientDetails() - rtUtils.AddSigningKeyNameHeader(operation.getOperationParams().SigningKeyName, &httpClientDetails.Headers) + rtUtils.AddSigningKeyNameHeader(operation.getSigningKeyName(), &httpClientDetails.Headers) rtUtils.SetContentType("application/json", &httpClientDetails.Headers) content, err := json.Marshal(operation.getRequestBody()) @@ -79,13 +80,7 @@ type ReleaseBundleDetails struct { ReleaseBundleVersion string `json:"release_bundle_version,omitempty"` } -type CreateOrPromoteReleaseBundleParams struct { - ReleaseBundleQueryParams - // Header: - SigningKeyName string -} - -type ReleaseBundleQueryParams struct { +type CommonOptionalQueryParams struct { ProjectKey string Async bool } diff --git a/lifecycle/services/promote.go b/lifecycle/services/promote.go index 7d767c5a7..dd66c8c4c 100644 --- a/lifecycle/services/promote.go +++ b/lifecycle/services/promote.go @@ -12,9 +12,10 @@ const ( ) type promoteOperation struct { - reqBody RbPromotionBody - rbDetails ReleaseBundleDetails - params CreateOrPromoteReleaseBundleParams + reqBody RbPromotionBody + rbDetails ReleaseBundleDetails + queryParams CommonOptionalQueryParams + signingKeyName string } func (p *promoteOperation) getOperationRestApi() string { @@ -29,18 +30,20 @@ func (p *promoteOperation) getOperationSuccessfulMsg() string { return "Release Bundle successfully promoted" } -func (p *promoteOperation) getOperationParams() CreateOrPromoteReleaseBundleParams { - return p.params +func (p *promoteOperation) getOperationParams() CommonOptionalQueryParams { + return p.queryParams } -func (rbs *ReleaseBundlesService) Promote(rbDetails ReleaseBundleDetails, params CreateOrPromoteReleaseBundleParams, environment string, overwrite bool) (RbPromotionResp, error) { +func (p *promoteOperation) getSigningKeyName() string { + return p.signingKeyName +} + +func (rbs *ReleaseBundlesService) Promote(rbDetails ReleaseBundleDetails, queryParams CommonOptionalQueryParams, signingKeyName string, promotionParams RbPromotionParams) (RbPromotionResp, error) { operation := promoteOperation{ - reqBody: RbPromotionBody{ - Environment: environment, - Overwrite: overwrite, - }, - rbDetails: rbDetails, - params: params, + reqBody: RbPromotionBody(promotionParams), + rbDetails: rbDetails, + queryParams: queryParams, + signingKeyName: signingKeyName, } respBody, err := rbs.doOperation(&operation) if err != nil { @@ -51,9 +54,14 @@ func (rbs *ReleaseBundlesService) Promote(rbDetails ReleaseBundleDetails, params return promotionResp, errorutils.CheckError(err) } +type RbPromotionParams struct { + Environment string + IncludedRepositoryKeys []string + ExcludedRepositoryKeys []string +} + type RbPromotionBody struct { Environment string `json:"environment,omitempty"` - Overwrite bool `json:"overwrite_existing_artifacts,omitempty"` IncludedRepositoryKeys []string `json:"included_repository_keys,omitempty"` ExcludedRepositoryKeys []string `json:"excluded_repository_keys,omitempty"` } diff --git a/pipelines/manager.go b/pipelines/manager.go index f6f723b5a..bda816e76 100644 --- a/pipelines/manager.go +++ b/pipelines/manager.go @@ -94,6 +94,12 @@ func (sm *PipelinesServicesManager) GetAllIntegrations() ([]services.Integration return integrationsService.GetAllIntegrations() } +func (sm *PipelinesServicesManager) GetAllRawIntegrations() ([]byte, error) { + integrationsService := services.NewIntegrationsService(sm.client) + integrationsService.ServiceDetails = sm.config.GetServiceDetails() + return integrationsService.GetAllRawIntegrations() +} + func (sm *PipelinesServicesManager) DeleteIntegration(integrationId int) error { integrationsService := services.NewIntegrationsService(sm.client) integrationsService.ServiceDetails = sm.config.GetServiceDetails() diff --git a/pipelines/services/integration.go b/pipelines/services/integration.go index 22f3f0535..cc71c6243 100644 --- a/pipelines/services/integration.go +++ b/pipelines/services/integration.go @@ -240,6 +240,18 @@ func (is *IntegrationsService) GetIntegrationByName(name string) (*Integration, } func (is *IntegrationsService) GetAllIntegrations() ([]Integration, error) { + rawIntegrations, err := is.GetAllRawIntegrations() + if err != nil { + return nil, err + } + integrations := &[]Integration{} + err = json.Unmarshal(rawIntegrations, integrations) + return *integrations, errorutils.CheckError(err) +} + +// GetAllRawIntegrations returns the response returned from integrations api without unmarshalling +// into Integration struct. +func (is *IntegrationsService) GetAllRawIntegrations() ([]byte, error) { log.Debug("Fetching all integrations...") httpDetails := is.ServiceDetails.CreateHttpClientDetails() url := is.ServiceDetails.GetUrl() + integrationsRestApi @@ -250,9 +262,7 @@ func (is *IntegrationsService) GetAllIntegrations() ([]Integration, error) { if err = errorutils.CheckResponseStatusWithBody(resp, body, http.StatusOK); err != nil { return nil, err } - integrations := &[]Integration{} - err = json.Unmarshal(body, integrations) - return *integrations, errorutils.CheckError(err) + return body, errorutils.CheckError(err) } type IntegrationAlreadyExistsError struct { diff --git a/tests/artifactoryfederatedrepository_test.go b/tests/artifactoryfederatedrepository_test.go index 739e97a0b..16e68c165 100644 --- a/tests/artifactoryfederatedrepository_test.go +++ b/tests/artifactoryfederatedrepository_test.go @@ -45,6 +45,7 @@ func TestArtifactoryFederatedRepository(t *testing.T) { t.Run("federatedRpmTest", federatedRpmTest) t.Run("federatedSbtTest", federatedSbtTest) t.Run("federatedSwiftTest", federatedSwiftTest) + t.Run("federatedTerraformTest", federatedTerraformTest) t.Run("federatedVagrantTest", federatedVagrantTest) t.Run("federatedYumTest", federatedYumTest) t.Run("federatedCreateWithParamTest", federatedCreateWithParamTest) @@ -654,6 +655,27 @@ func federatedSwiftTest(t *testing.T) { } } +func federatedTerraformTest(t *testing.T) { + repoKey := GenerateRepoKeyForRepoServiceTest() + tfp := services.NewTerraformFederatedRepositoryParams() + tfp.Key = repoKey + setFederatedRepositoryBaseParams(&tfp.FederatedRepositoryBaseParams, false) + + err := testsCreateFederatedRepositoryService.Terraform(tfp) + if !assert.NoError(t, err, "Failed to create "+repoKey) { + return + } + defer deleteRepo(t, repoKey) + validateRepoConfig(t, repoKey, tfp) + + setFederatedRepositoryBaseParams(&tfp.FederatedRepositoryBaseParams, true) + + err = testsUpdateFederatedRepositoryService.Terraform(tfp) + if assert.NoError(t, err, "Failed to update "+repoKey) { + validateRepoConfig(t, repoKey, tfp) + } +} + func federatedVagrantTest(t *testing.T) { repoKey := GenerateRepoKeyForRepoServiceTest() vfp := services.NewVagrantFederatedRepositoryParams() diff --git a/tests/artifactorylocalrepository_test.go b/tests/artifactorylocalrepository_test.go index 161cd8e21..54de21404 100644 --- a/tests/artifactorylocalrepository_test.go +++ b/tests/artifactorylocalrepository_test.go @@ -37,6 +37,7 @@ func TestArtifactoryLocalRepository(t *testing.T) { t.Run("localRpmTest", localRpmTest) t.Run("localSbtTest", localSbtTest) t.Run("localSwiftTest", localSwiftTest) + t.Run("localTerraformTest", localTerraformTest) t.Run("localVagrantTest", localVagrantTest) t.Run("localYumTest", localYumTest) t.Run("localCreateWithParamTest", localCreateWithParamTest) @@ -640,6 +641,27 @@ func localSwiftTest(t *testing.T) { } } +func localTerraformTest(t *testing.T) { + repoKey := GenerateRepoKeyForRepoServiceTest() + tlp := services.NewTerraformLocalRepositoryParams() + tlp.Key = repoKey + setLocalRepositoryBaseParams(&tlp.LocalRepositoryBaseParams, false) + + err := testsCreateLocalRepositoryService.Terraform(tlp) + if !assert.NoError(t, err, "Failed to create "+repoKey) { + return + } + defer deleteRepo(t, repoKey) + validateRepoConfig(t, repoKey, tlp) + + setLocalRepositoryBaseParams(&tlp.LocalRepositoryBaseParams, true) + + err = testsUpdateLocalRepositoryService.Terraform(tlp) + if assert.NoError(t, err, "Failed to update "+repoKey) { + validateRepoConfig(t, repoKey, tlp) + } +} + func localVagrantTest(t *testing.T) { repoKey := GenerateRepoKeyForRepoServiceTest() vlp := services.NewVagrantLocalRepositoryParams() diff --git a/tests/artifactoryremoterepository_test.go b/tests/artifactoryremoterepository_test.go index f9d10bea0..5c5e74920 100644 --- a/tests/artifactoryremoterepository_test.go +++ b/tests/artifactoryremoterepository_test.go @@ -134,7 +134,7 @@ func remoteAlpineTest(t *testing.T) { repoKey := GenerateRepoKeyForRepoServiceTest() arp := services.NewAlpineRemoteRepositoryParams() arp.Key = repoKey - arp.Url = "http://dl-cdn.alpinelinux.org/alpine" + arp.Url = "https://dl-cdn.alpinelinux.org/alpine" setRemoteRepositoryBaseParams(&arp.RemoteRepositoryBaseParams, false) err := testsCreateRemoteRepositoryService.Alpine(arp) @@ -344,7 +344,7 @@ func remoteDebianTest(t *testing.T) { repoKey := GenerateRepoKeyForRepoServiceTest() drp := services.NewDebianRemoteRepositoryParams() drp.Key = repoKey - drp.Url = "http://archive.ubuntu.com/ubuntu/" + drp.Url = "https://archive.ubuntu.com/ubuntu/" setRemoteRepositoryBaseParams(&drp.RemoteRepositoryBaseParams, false) drp.ListRemoteFolderItems = utils.Pointer(true) @@ -737,7 +737,7 @@ func remoteRpmTest(t *testing.T) { repoKey := GenerateRepoKeyForRepoServiceTest() rrp := services.NewRpmRemoteRepositoryParams() rrp.Key = repoKey - rrp.Url = "http://mirror.centos.org/centos/" + rrp.Url = "https://mirror.centos.org/centos/" setRemoteRepositoryBaseParams(&rrp.RemoteRepositoryBaseParams, false) rrp.ListRemoteFolderItems = utils.Pointer(true) @@ -805,24 +805,24 @@ func remoteSwiftTest(t *testing.T) { func remoteTerraformTest(t *testing.T) { repoKey := GenerateRepoKeyForRepoServiceTest() - srp := services.NewTerraformRemoteRepositoryParams() - srp.Key = repoKey - srp.Url = "https://github.com" - setRemoteRepositoryBaseParams(&srp.RemoteRepositoryBaseParams, false) + trp := services.NewTerraformRemoteRepositoryParams() + trp.Key = repoKey + trp.Url = "https://github.com" + setRemoteRepositoryBaseParams(&trp.RemoteRepositoryBaseParams, false) - err := testsCreateRemoteRepositoryService.Terraform(srp) + err := testsCreateRemoteRepositoryService.Terraform(trp) if !assert.NoError(t, err, "Failed to create "+repoKey) { return } defer deleteRepo(t, repoKey) - validateRepoConfig(t, repoKey, srp) + validateRepoConfig(t, repoKey, trp) - setRemoteRepositoryBaseParams(&srp.RemoteRepositoryBaseParams, true) + setRemoteRepositoryBaseParams(&trp.RemoteRepositoryBaseParams, true) // Due to a bug on Artifactory side that prevents the update of "bypassHeadRequests" field to false on terraform we leave it unchanged. - srp.BypassHeadRequests = utils.Pointer(true) - err = testsUpdateRemoteRepositoryService.Terraform(srp) + trp.BypassHeadRequests = utils.Pointer(true) + err = testsUpdateRemoteRepositoryService.Terraform(trp) if assert.NoError(t, err, "Failed to update "+repoKey) { - validateRepoConfig(t, repoKey, srp) + validateRepoConfig(t, repoKey, trp) } } @@ -856,7 +856,7 @@ func remoteYumTest(t *testing.T) { repoKey := GenerateRepoKeyForRepoServiceTest() yrp := services.NewYumRemoteRepositoryParams() yrp.Key = repoKey - yrp.Url = "http://mirror.centos.org/centos/" + yrp.Url = "https://mirror.centos.org/centos/" setRemoteRepositoryBaseParams(&yrp.RemoteRepositoryBaseParams, false) yrp.ListRemoteFolderItems = utils.Pointer(true) diff --git a/tests/artifactoryvirtualrepository_test.go b/tests/artifactoryvirtualrepository_test.go index 5ee5aa90e..a9ccfa5f9 100644 --- a/tests/artifactoryvirtualrepository_test.go +++ b/tests/artifactoryvirtualrepository_test.go @@ -656,26 +656,26 @@ func virtualSwiftTest(t *testing.T) { func virtualTerraformTest(t *testing.T) { repoKey := GenerateRepoKeyForRepoServiceTest() - avp := services.NewTerraformVirtualRepositoryParams() - avp.Key = repoKey - setVirtualRepositoryBaseParams(&avp.VirtualRepositoryBaseParams, false) - setCacheVirtualRepositoryParams(&avp.CommonCacheVirtualRepositoryParams, false) + tvp := services.NewTerraformVirtualRepositoryParams() + tvp.Key = repoKey + setVirtualRepositoryBaseParams(&tvp.VirtualRepositoryBaseParams, false) + setCacheVirtualRepositoryParams(&tvp.CommonCacheVirtualRepositoryParams, false) - err := testsCreateVirtualRepositoryService.Terraform(avp) + err := testsCreateVirtualRepositoryService.Terraform(tvp) if !assert.NoError(t, err, "Failed to create "+repoKey) { return } defer deleteRepo(t, repoKey) - validateRepoConfig(t, repoKey, avp) + validateRepoConfig(t, repoKey, tvp) - setVirtualRepositoryBaseParams(&avp.VirtualRepositoryBaseParams, true) - setCacheVirtualRepositoryParams(&avp.CommonCacheVirtualRepositoryParams, true) + setVirtualRepositoryBaseParams(&tvp.VirtualRepositoryBaseParams, true) + setCacheVirtualRepositoryParams(&tvp.CommonCacheVirtualRepositoryParams, true) - err = testsUpdateVirtualRepositoryService.Terraform(avp) + err = testsUpdateVirtualRepositoryService.Terraform(tvp) assert.NoError(t, err, "Failed to update "+repoKey) - validateRepoConfig(t, repoKey, avp) + validateRepoConfig(t, repoKey, tvp) if assert.NoError(t, err, "Failed to update "+repoKey) { - validateRepoConfig(t, repoKey, avp) + validateRepoConfig(t, repoKey, tvp) } } diff --git a/tests/pipelinesintegrations_test.go b/tests/pipelinesintegrations_test.go index 254e15b5d..cf935328f 100644 --- a/tests/pipelinesintegrations_test.go +++ b/tests/pipelinesintegrations_test.go @@ -24,6 +24,7 @@ func TestPipelinesIntegrations(t *testing.T) { t.Run(services.BitbucketServerName, testCreateBitbucketServerIntegration) t.Run(services.GitlabName, testCreateGitlabIntegration) t.Run(services.ArtifactoryName, testCreateArtifactoryIntegration) + t.Run("GetAllIntegrations", getAllIntegrationAndAssert) } func testCreateGithubIntegrationAndGetByName(t *testing.T) { @@ -104,6 +105,31 @@ func getIntegrationAndAssert(t *testing.T, id int, name, integrationType string) assert.Equal(t, integrationType, integration.MasterIntegrationName) } +func getAllIntegrationAndAssert(t *testing.T) { + // Create Artifactory Integration + name := getUniqueIntegrationName(services.ArtifactoryName) + id, err := testsPipelinesIntegrationsService.CreateArtifactoryIntegration(name, testsDummyRtUrl, testsDummyUser, testsDummyApiKey) + if !assert.NoError(t, err) { + return + } + defer deleteIntegrationAndAssert(t, id) + + // Create Gitlab Integration + name = getUniqueIntegrationName(services.GitlabName) + gitlabIntegrationId, err := testsPipelinesIntegrationsService.CreateGitlabIntegration(name, testsDummyVcsUrl, testsDummyToken) + if !assert.NoError(t, err) { + return + } + defer deleteIntegrationAndAssert(t, gitlabIntegrationId) + + integrations, err := testsPipelinesIntegrationsService.GetAllIntegrations() + if !assert.NoError(t, err) { + return + } + assert.NotNil(t, integrations) + assert.True(t, len(integrations) > 2) +} + func getUniqueIntegrationName(integrationType string) string { return strings.Join([]string{integrationNamesPrefix, integrationType, getCustomRunId('_')}, "_") } diff --git a/tests/xray_test.go b/tests/xray_test.go index fb05cd149..7447dccba 100644 --- a/tests/xray_test.go +++ b/tests/xray_test.go @@ -27,7 +27,7 @@ func TestXrayVersion(t *testing.T) { func TestXrayEntitlementsService(t *testing.T) { initXrayTest(t) - xrayServerPort := xray.StartXrayMockServer() + xrayServerPort := xray.StartXrayMockServer(t) xrayDetails := GetXrayDetails() client, err := jfroghttpclient.JfrogClientBuilder(). SetClientCertPath(xrayDetails.GetClientCertPath()). @@ -69,7 +69,7 @@ func testEntitlements(t *testing.T, featureId string, expected bool) { func TestScanBuild(t *testing.T) { initXrayTest(t) - xrayServerPort := xray.StartXrayMockServer() + xrayServerPort := xray.StartXrayMockServer(t) xrayDetails := newTestXrayDetails(GetXrayDetails()) client, err := jfroghttpclient.JfrogClientBuilder(). SetClientCertPath(xrayDetails.GetClientCertPath()). diff --git a/tests/xrayreport_test.go b/tests/xrayreport_test.go index ab5a5bd58..00ff4e71d 100644 --- a/tests/xrayreport_test.go +++ b/tests/xrayreport_test.go @@ -16,7 +16,7 @@ var testXrayReportService *services.ReportService func TestXrayReport(t *testing.T) { initXrayTest(t) - xrayServerPort := xray.StartXrayMockServer() + xrayServerPort := xray.StartXrayMockServer(t) xrayDetails := GetXrayDetails() client, err := jfroghttpclient.JfrogClientBuilder(). SetClientCertPath(xrayDetails.GetClientCertPath()). diff --git a/tests/xrayscan_test.go b/tests/xrayscan_test.go index a1c46d8ef..d031c25fb 100644 --- a/tests/xrayscan_test.go +++ b/tests/xrayscan_test.go @@ -1,6 +1,8 @@ package tests import ( + "github.com/jfrog/jfrog-client-go/auth" + "github.com/stretchr/testify/assert" "strconv" "strings" "testing" @@ -8,13 +10,15 @@ import ( "github.com/jfrog/jfrog-client-go/artifactory/services" "github.com/jfrog/jfrog-client-go/artifactory/services/utils/tests/xray" "github.com/jfrog/jfrog-client-go/http/jfroghttpclient" + xrayServices "github.com/jfrog/jfrog-client-go/xray/services" ) var testsXrayScanService *services.XrayScanService +var testsScanService *xrayServices.ScanService func TestNewXrayScanService(t *testing.T) { initXrayTest(t) - xrayServerPort := xray.StartXrayMockServer() + xrayServerPort := xray.StartXrayMockServer(t) artDetails := GetRtDetails() client, err := jfroghttpclient.JfrogClientBuilder(). SetClientCertPath(artDetails.GetClientCertPath()). @@ -60,3 +64,59 @@ func scanBuild(t *testing.T, buildName, buildNumber, expected string) { t.Error("Expected:", expected, "Got: ", string(result)) } } + +func TestIsXscEnabled(t *testing.T) { + xrayServerPort, xrayDetails, client := initXrayScanTest(t) + testsScanService = xrayServices.NewScanService(client) + testsScanService.XrayDetails = xrayDetails + testsScanService.XrayDetails.SetUrl("http://localhost:" + strconv.Itoa(xrayServerPort) + "/xray/") + + result, err := testsScanService.IsXscEnabled() + assert.NoError(t, err) + assert.Equal(t, xray.TestXscVersion, result) +} + +func TestSendScanGitInfoContext(t *testing.T) { + xrayServerPort, xrayDetails, client := initXrayScanTest(t) + testsScanService = xrayServices.NewScanService(client) + testsScanService.XrayDetails = xrayDetails + testsScanService.XrayDetails.SetUrl("http://localhost:" + strconv.Itoa(xrayServerPort) + "/xray/") + + // Run tests + tests := []struct { + name string + gitInfoContext *xrayServices.XscGitInfoContext + expected string + }{ + {name: "ValidGitInfoContext", gitInfoContext: &xray.GitInfoContextWithMinimalRequiredFields, expected: xray.TestMultiScanId}, + {name: "InvalidGitInfoContext", gitInfoContext: &xray.GitInfoContextWithMissingFields, expected: xray.XscGitInfoBadResponse}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + sendGitInfoContext(t, test.gitInfoContext, test.expected) + }) + } +} + +func sendGitInfoContext(t *testing.T, gitInfoContext *xrayServices.XscGitInfoContext, expected string) { + result, err := testsScanService.SendScanGitInfoContext(gitInfoContext) + if err != nil { + assert.ErrorContains(t, err, expected) + return + } + assert.Equal(t, expected, result) +} + +func initXrayScanTest(t *testing.T) (xrayServerPort int, xrayDetails auth.ServiceDetails, client *jfroghttpclient.JfrogHttpClient) { + var err error + initXrayTest(t) + xrayServerPort = xray.StartXrayMockServer(t) + xrayDetails = GetXrayDetails() + client, err = jfroghttpclient.JfrogClientBuilder(). + SetClientCertPath(xrayDetails.GetClientCertPath()). + SetClientCertKeyPath(xrayDetails.GetClientCertKeyPath()). + AppendPreRequestInterceptor(xrayDetails.RunPreRequestFunctions). + Build() + assert.NoError(t, err) + return +} diff --git a/tests/xraysummary_test.go b/tests/xraysummary_test.go index f5d7ea4f3..037bb9b77 100644 --- a/tests/xraysummary_test.go +++ b/tests/xraysummary_test.go @@ -17,7 +17,7 @@ var testsXraySummaryService *services.SummaryService func TestNewXraySummaryService(t *testing.T) { initXrayTest(t) - xrayServerPort := xray.StartXrayMockServer() + xrayServerPort := xray.StartXrayMockServer(t) xrayDetails := GetXrayDetails() client, err := jfroghttpclient.JfrogClientBuilder(). SetClientCertPath(xrayDetails.GetClientCertPath()). diff --git a/utils/utils.go b/utils/utils.go index 99a9a9a0e..707fedbde 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -27,7 +27,7 @@ import ( const ( Development = "development" Agent = "jfrog-client-go" - Version = "1.36.1" + Version = "1.37.0" ) type MinVersionProduct string diff --git a/xray/manager.go b/xray/manager.go index ac15b6e58..33fa30c66 100644 --- a/xray/manager.go +++ b/xray/manager.go @@ -204,3 +204,10 @@ func (sm *XrayServicesManager) XscEnabled() (string, error) { scanService.XrayDetails = sm.config.GetServiceDetails() return scanService.IsXscEnabled() } + +// SendXscGitInfoRequest sends git info details to xsc service and gets multi scan id +func (sm *XrayServicesManager) SendXscGitInfoRequest(details *services.XscGitInfoContext) (multiScanId string, err error) { + scanService := services.NewScanService(sm.client) + scanService.XrayDetails = sm.config.GetServiceDetails() + return scanService.SendScanGitInfoContext(details) +} diff --git a/xray/services/scan.go b/xray/services/scan.go index 18f49dc6b..bf3d485f1 100644 --- a/xray/services/scan.go +++ b/xray/services/scan.go @@ -2,11 +2,9 @@ package services import ( "encoding/json" - "fmt" "github.com/jfrog/jfrog-client-go/utils/log" xrayUtils "github.com/jfrog/jfrog-client-go/xray/services/utils" "net/http" - "os" "strings" "time" @@ -42,7 +40,7 @@ const ( xrayScanStatusFailed = "failed" // Xsc consts - postScanContextAPI = "api/v1/gitinfo" + postXscGitInfoContextAPI = "api/v1/gitinfo" XscGraphAPI = "api/v1/sca/scan/graph" @@ -106,18 +104,6 @@ func createScanGraphQueryParams(scanParams XrayGraphScanParams) string { } func (ss *ScanService) ScanGraph(scanParams XrayGraphScanParams) (string, error) { - if scanParams.XscVersion != "" && scanParams.XscGitInfoContext != nil { - multiScanId, err := ss.SendScanGitInfoContext(scanParams.XscGitInfoContext) - if err != nil { - return "", fmt.Errorf("failed sending Git Info to XSC service, error: %s ", err.Error()) - } - scanParams.MultiScanId = multiScanId - if err = os.Setenv("JF_MSI", multiScanId); err != nil { - // Not a fatal error, if not set the scan will not be shown at the XSC UI, should not fail the scan. - log.Debug(fmt.Sprintf("failed setting MSI as environment variable. Cause: %s", err.Error())) - } - } - httpClientsDetails := ss.XrayDetails.CreateHttpClientDetails() utils.SetContentType("application/json", &httpClientsDetails.Headers) var err error @@ -224,7 +210,7 @@ func (ss *ScanService) SendScanGitInfoContext(details *XscGitInfoContext) (multi if err != nil { return "", errorutils.CheckError(err) } - url := ss.xrayToXscUrl() + postScanContextAPI + url := ss.xrayToXscUrl() + postXscGitInfoContextAPI resp, body, err := ss.client.SendPost(url, requestBody, &httpClientsDetails) if err != nil { return @@ -394,15 +380,15 @@ type XscVersionResponse struct { type XscGitInfoContext struct { GitRepoUrl string `json:"git_repo_url"` - GitRepoName string `json:"git_repo_name"` - GitProject string `json:"git_project"` - GitProvider string `json:"git_provider"` - Technologies []string `json:"technologies"` + GitRepoName string `json:"git_repo_name,omitempty"` + GitProject string `json:"git_project,omitempty"` + GitProvider string `json:"git_provider,omitempty"` + Technologies []string `json:"technologies,omitempty"` BranchName string `json:"branch_name"` - LastCommit string `json:"last_commit"` + LastCommit string `json:"last_commit,omitempty"` CommitHash string `json:"commit_hash"` - CommitMessage string `json:"commit_message"` - CommitAuthor string `json:"commit_author"` + CommitMessage string `json:"commit_message,omitempty"` + CommitAuthor string `json:"commit_author,omitempty"` } func (gp *XrayGraphScanParams) GetProjectKey() string { From 57a5a36f5c070c22400c4e91476c98628c515a52 Mon Sep 17 00:00:00 2001 From: Felix Ohnesorge Date: Thu, 16 May 2024 19:48:14 +0200 Subject: [PATCH 09/10] corrected json tag for license field in report --- xray/services/report.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/xray/services/report.go b/xray/services/report.go index ee387f8ed..685a37efe 100644 --- a/xray/services/report.go +++ b/xray/services/report.go @@ -3,11 +3,12 @@ package services import ( "encoding/json" "fmt" + "net/http" + "github.com/jfrog/jfrog-client-go/artifactory/services/utils" "github.com/jfrog/jfrog-client-go/auth" "github.com/jfrog/jfrog-client-go/http/jfroghttpclient" "github.com/jfrog/jfrog-client-go/utils/errorutils" - "net/http" ) const ( @@ -76,7 +77,7 @@ type Row struct { ExternalAdvisorySource string `json:"external_advisory_source,omitempty"` ExternalAdvisorySeverity string `json:"external_advisory_severity,omitempty"` // Licenses Report field - License string `json:"license,omitempty"` + License string `json:"license_key,omitempty"` LicenseName string `json:"license_name,omitempty"` Component string `json:"component,omitempty"` Artifact string `json:"artifact,omitempty"` From 6c2b4a2bcd0b945c118a2f2551b4347cc7d40c38 Mon Sep 17 00:00:00 2001 From: Felix Ohnesorge Date: Thu, 16 May 2024 19:49:01 +0200 Subject: [PATCH 10/10] added missing watchRecipients field for watch --- xray/services/utils/watchbody.go | 7 ++++++- xray/services/watch.go | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/xray/services/utils/watchbody.go b/xray/services/utils/watchbody.go index aee708ff3..2a68a3762 100644 --- a/xray/services/utils/watchbody.go +++ b/xray/services/utils/watchbody.go @@ -47,7 +47,8 @@ func NewWatchParams() WatchParams { Builds: WatchBuildsParams{ ByNames: make(map[string]WatchBuildsByNameParams, 0), }, - Policies: make([]AssignedPolicy, 0), + Policies: make([]AssignedPolicy, 0), + WatchRecipients: make([]string, 0), } } @@ -61,6 +62,8 @@ type WatchParams struct { Builds WatchBuildsParams Policies []AssignedPolicy + + WatchRecipients []string } // WatchRepositoriesParams is a struct that stores the repository configuration for watch @@ -120,6 +123,7 @@ type WatchBody struct { GeneralData watchGeneralParams `json:"general_data"` ProjectResources watchProjectResources `json:"project_resources,omitempty"` AssignedPolicies []AssignedPolicy `json:"assigned_policies,omitempty"` + WatchRecipients []string `json:"watch_recipients"` } // These structs are internal @@ -175,6 +179,7 @@ func CreateBody(params WatchParams) (*WatchBody, error) { Resources: []watchProjectResourcesElement{}, }, AssignedPolicies: params.Policies, + WatchRecipients: params.WatchRecipients, } err := configureRepositories(&payloadBody, params) diff --git a/xray/services/watch.go b/xray/services/watch.go index ae356e0b7..09274ba9d 100644 --- a/xray/services/watch.go +++ b/xray/services/watch.go @@ -182,6 +182,7 @@ func (xws *WatchService) Get(watchName string) (watchResp *utils.WatchParams, er ByNames: map[string]utils.WatchBuildsByNameParams{}, } result.Policies = watch.AssignedPolicies + result.WatchRecipients = watch.WatchRecipients utils.UnpackWatchBody(&result, &watch)