Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
EyalDelarea committed Apr 15, 2024
2 parents 109a52e + 84428ab commit 80b1846
Show file tree
Hide file tree
Showing 22 changed files with 874 additions and 36 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ jobs:
strategy:
fail-fast: false
matrix:
suite: [ distribution, xray, mpu ]
suite: [ distribution, xray, xsc, mpu ]
os: [ ubuntu, windows, macos ]
runs-on: ${{ matrix.os }}-latest
steps:
Expand All @@ -114,7 +114,7 @@ jobs:
restore-keys: ${{ runner.os }}-go-

- name: ${{ matrix.suite }} tests
run: go test -v github.com/jfrog/jfrog-client-go/tests --timeout 0 --test.${{ matrix.suite }} --rt.url=${{ secrets.PLATFORM_URL }}/artifactory --ds.url=${{ secrets.PLATFORM_URL }}/distribution --xr.url=${{ secrets.PLATFORM_URL }}/xray --access.url=${{ secrets.PLATFORM_URL }}/access --rt.user=${{ secrets.PLATFORM_USER }} --rt.password=${{ secrets.PLATFORM_PASSWORD }} --access.token=${{ secrets.PLATFORM_ADMIN_TOKEN }} --ci.runId=${{ runner.os }}-${{ matrix.suite }}
run: go test -v github.com/jfrog/jfrog-client-go/tests --timeout 0 --test.${{ matrix.suite }} --rt.url=${{ secrets.PLATFORM_URL }}/artifactory --ds.url=${{ secrets.PLATFORM_URL }}/distribution --xr.url=${{ secrets.PLATFORM_URL }}/xray --xsc.url=${{ secrets.PLATFORM_URL }}/xsc --access.url=${{ secrets.PLATFORM_URL }}/access --rt.user=${{ secrets.PLATFORM_USER }} --rt.password=${{ secrets.PLATFORM_PASSWORD }} --access.token=${{ secrets.PLATFORM_ADMIN_TOKEN }} --ci.runId=${{ runner.os }}-${{ matrix.suite }}

JFrog-Client-Go-Pipelines-Tests:
needs: Pretest
Expand Down
106 changes: 96 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,17 @@
- [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)
- [XSC APIs](#xsc-apis)
- [Creating XSC Service Manager](#creating-xray-service-manager)
- [Creating XSC Details](#creating-xsc-details)
- [Creating XSC Service Config](#creating-xsc-service-config)
- [Creating New XSC Service Manager](#creating-new-xsc-service-manager)
- [Using XSC Services](#using-xsc-services)
- [Fetching XSC's Version](#fetching-xscs-version)
- [Report XSC analytics metrics](#report-xsc-analytics-metrics)
- [Add analytics general event](#add-analytics-general-event)
- [Update analytics general event](#update-analytics-general-event)
- [Get analytics general event](#get-analytics-general-event)
- [Pipelines APIs](#pipelines-apis)
- [Creating Pipelines Service Manager](#creating-pipelines-service-manager)
- [Creating Pipelines Details](#creating-pipelines-details)
Expand Down Expand Up @@ -215,6 +223,7 @@
- [Delete Release Bundle Version](#delete-release-bundle-version)
- [Delete Release Bundle Version Promotion](#delete-release-bundle-version-promotion)
- [Export Release Bundle](#export-release-bundle)
- [Import Release Bundle](#import-release-bundle)
- [Remote Delete Release Bundle](#remote-delete-release-bundle)

## General
Expand Down Expand Up @@ -265,6 +274,7 @@ content of this repository is deleted.
| `-test.artifactory` | Artifactory tests | Artifactory Pro |
| `-test.distribution` | Distribution tests | Artifactory with Distribution |
| `-test.xray` | Xray tests | Artifactory with Xray |
| `-test.xsc` | Xsc tests | Xray with Xsc |
| `-test.pipelines` | Pipelines tests | JFrog Pipelines |
| `-test.access` | Access tests | Artifactory Pro |
| `-test.repositories` | Repositories tests | Artifactory Pro |
Expand All @@ -277,6 +287,7 @@ content of this repository is deleted.
| `-rt.url` | [Default: http://localhost:8081/artifactory] Artifactory URL. |
| `-ds.url` | [Optional] JFrog Distribution URL. |
| `-xr.url` | [Optional] JFrog Xray URL. |
| `-xsc.url` | [Optional] JFrog Xsc URL. |
| `-pipe.url` | [Optional] JFrog Pipelines URL. |
| `-access.url` | [Optional] JFrog Access URL. |
| `-rt.user` | [Default: admin] Artifactory username. |
Expand Down Expand Up @@ -2233,20 +2244,88 @@ artifactSummary, err := xrayManager.ArtifactSummary(artifactSummaryRequest)
isEntitled, err := xrayManager.IsEntitled(featureId)
```
### Using XSC Service
#### Check if xsc is enabled
## XSC APIs
### Creating XSC Service Manager
#### Creating XSC Details
```go
xscDetails := auth.NewXscDetails()
xscDetails.SetUrl("http://localhost:8081/xsc")
xscDetails.SetSshKeyPath("path/to/.ssh/")
xscDetails.SetApiKey("apikey")
xscDetails.SetUser("user")
xscDetails.SetPassword("password")
xscDetails.SetAccessToken("accesstoken")
// if client certificates are required
xscDetails.SetClientCertPath("path/to/.cer")
xscDetails.SetClientCertKeyPath("path/to/.key")
```
#### Creating XSC Service Config
```go
serviceConfig, err := config.NewConfigBuilder().
SetServiceDetails(xscDetails).
SetCertificatesPath(certPath).
// Optionally overwrite the default HTTP retries, which is set to 3.
SetHttpRetries(8).
Build()
```
#### Creating New XSC Service Manager
```go
// Will try to get XSC version. If route is not available, user is not entitled for XSC.
xscVersion, err := scanService.IsXscEnabled()
xscManager, err := xsc.New(serviceConfig)
```
#### Send git info details to xsc
### Using XSC Services
#### Fetching XSC's Version
```go
version, err := xscManager.GetVersion()
```
#### Report XSC analytics metrics
##### Add analytics general event
Sent XSC a new event which contains analytics data, and get multi-scan id back from XSC.
```go
// Details are the git info details (gitRepoUrl, branchName, commitHash are required fields). Returns multi scan id.
multiScanId, err := scanService.SendScanGitInfoContext(details)
event := services.XscAnalyticsGeneralEvent{
XscAnalyticsBasicGeneralEvent: services.XscAnalyticsBasicGeneralEvent{
EventType: services.CliEventType,
Product: services.CliProduct,
ProductVersion: "2.53.1",
IsDefaultConfig: false,
JfrogUser: "gail",
OsPlatform: "mac",
OsArchitecture: "arm64",
AnalyzerManagerVersion: "1.1.1",
EventStatus: services.Started,
}}
msi, err := xscManager.AddAnalyticsGeneralEvent(event)
```
##### Update analytics general event
Sent XSC a finalized analytics metrics event with information matching an existing event's msi.
```go
finalizeEvent := services.XscAnalyticsGeneralEventFinalize{
MultiScanId: msi,
XscAnalyticsBasicGeneralEvent: services.XscAnalyticsBasicGeneralEvent{
EventStatus: services.Completed,
TotalFindings: 10,
TotalIgnoredFindings: 5,
TotalScanDuration: "15s",
},
}
err := xscManager.UpdateAnalyticsGeneralEvent(finalizeEvent)
```
##### Get analytics general event
Get a general event from XSC matching the provided msi.
```go
event, err := xscManager.GetAnalyticsGeneralEvent(msi)
```
## Pipelines APIs
Expand Down Expand Up @@ -2627,6 +2706,13 @@ modifictions:= []utils.PathMapping{{
res,err:= serviceManager.ExportReleaseBundle(rbDetails, modifications, queryParams)
```
#### Import Release Bundle Archive
```go
// Imports an exported release bundle archive
res,err:= serviceManager.releaseService.ImportReleaseBundle(filePath)
```
#### Delete Release Bundle Version
```go
Expand Down
5 changes: 5 additions & 0 deletions artifactory/emptymanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ type ArtifactoryServicesManager interface {
FileList(relativePath string, optionalParams utils.FileListParams) (*utils.FileListResponse, error)
GetStorageInfo() (*utils.StorageInfo, error)
CalculateStorageInfo() error
ImportReleaseBundle(string) error
}

// By using this struct, you have the option of overriding only some of the ArtifactoryServicesManager
Expand Down Expand Up @@ -465,6 +466,10 @@ func (esm *EmptyArtifactoryServicesManager) CalculateStorageInfo() error {
panic("Failed: Method is not implemented")
}

func (esm *EmptyArtifactoryServicesManager) ImportReleaseBundle(string) error {
panic("Failed: Method is not implemented")
}

// Compile time check of interface implementation.
// Since EmptyArtifactoryServicesManager can be used by tests external to this project, we want this project's tests to fail,
// if EmptyArtifactoryServicesManager stops implementing the ArtifactoryServicesManager interface.
Expand Down
5 changes: 5 additions & 0 deletions artifactory/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,3 +605,8 @@ func (sm *ArtifactoryServicesManagerImp) CalculateStorageInfo() error {
storageService := services.NewStorageService(sm.config.GetServiceDetails(), sm.client)
return storageService.StorageInfoRefresh()
}

func (sm *ArtifactoryServicesManagerImp) ImportReleaseBundle(filePath string) error {
releaseService := services.NewReleaseService(sm.config.GetServiceDetails(), sm.client)
return releaseService.ImportReleaseBundle(filePath)
}
78 changes: 78 additions & 0 deletions artifactory/services/releasebundle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package services

import (
"encoding/json"
"github.com/jfrog/jfrog-client-go/artifactory/services/utils"
"github.com/jfrog/jfrog-client-go/auth"
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
utils2 "github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
"github.com/jfrog/jfrog-client-go/utils/log"
"net/http"
)

const (
conflictErrorMessage = "Bundle already exists"
ReleaseBundleImportRestApiEndpoint = "api/release/import/"
octetStream = "application/octet-stream"
)

type releaseService struct {
client *jfroghttpclient.JfrogHttpClient
ArtDetails auth.ServiceDetails
}

type ErrorResponseWithMessage struct {
Errors []ErrorDetail `json:"errors"`
}

type ErrorDetail struct {
Status int `json:"status"`
Message string `json:"message"`
}

func NewReleaseService(artDetails auth.ServiceDetails, client *jfroghttpclient.JfrogHttpClient) *releaseService {
return &releaseService{client: client, ArtDetails: artDetails}
}

func (rs *releaseService) GetJfrogHttpClient() *jfroghttpclient.JfrogHttpClient {
return rs.client
}

func (rs *releaseService) ImportReleaseBundle(filePath string) (err error) {
// Load desired file
content, err := fileutils.ReadFile(filePath)
if err != nil {
return
}
// Upload file
httpClientsDetails := rs.ArtDetails.CreateHttpClientDetails()

url := utils2.AddTrailingSlashIfNeeded(rs.ArtDetails.GetUrl() + ReleaseBundleImportRestApiEndpoint)

utils.SetContentType(octetStream, &httpClientsDetails.Headers)
var resp *http.Response
var body []byte
log.Info("Uploading archive...")
if resp, body, err = rs.client.SendPost(url, content, &httpClientsDetails); err != nil {
return
}
// When a release bundle already exists, the API returns 400.
// Check the error message, and if it's a conflict, don't fail the operation.
if resp.StatusCode == http.StatusBadRequest {
response := ErrorResponseWithMessage{}
if err = json.Unmarshal(body, &response); err != nil {
return
}
if response.Errors[0].Message == conflictErrorMessage {
log.Warn("Bundle already exists, did not upload a new bundle")
return
}
}
if err = errorutils.CheckResponseStatusWithBody(resp, body, http.StatusAccepted); err != nil {
return
}
log.Info("Release Bundle Imported Successfully")
return
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/gookit/color v1.5.4
github.com/jfrog/archiver/v3 v3.6.0
github.com/jfrog/build-info-go v1.9.25
github.com/jfrog/gofrog v1.6.3
github.com/jfrog/gofrog v1.7.1
github.com/stretchr/testify v1.9.0
github.com/xanzy/ssh-agent v0.3.3
golang.org/x/crypto v0.21.0
Expand Down Expand Up @@ -51,6 +51,7 @@ require (
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
golang.org/x/mod v0.16.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/tools v0.19.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
Expand Down
5 changes: 3 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ github.com/jfrog/archiver/v3 v3.6.0 h1:OVZ50vudkIQmKMgA8mmFF9S0gA47lcag22N13iV3F
github.com/jfrog/archiver/v3 v3.6.0/go.mod h1:fCAof46C3rAXgZurS8kNRNdSVMKBbZs+bNNhPYxLldI=
github.com/jfrog/build-info-go v1.9.25 h1:IkjydGQA/HjOWjRaoKq1hOEgCCyBEJwQgXJSo4WVBSA=
github.com/jfrog/build-info-go v1.9.25/go.mod h1:doFB4bFDVHeGulD6GF9LzsrRaIOrSoklV9DgIAEqHgc=
github.com/jfrog/gofrog v1.6.3 h1:F7He0+75HcgCe6SGTSHLFCBDxiE2Ja0tekvvcktW6wc=
github.com/jfrog/gofrog v1.6.3/go.mod h1:SZ1EPJUruxrVGndOzHd+LTiwWYKMlHqhKD+eu+v5Hqg=
github.com/jfrog/gofrog v1.7.1 h1:ME1Meg4hukAT/7X6HUQCVSe4DNjMZACCP8aCY37EW/w=
github.com/jfrog/gofrog v1.7.1/go.mod h1:X7bjfWoQDN0Z4FQGbE91j3gbPP7Urwzm4Z8tkvrlbRI=
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=
Expand Down Expand Up @@ -139,6 +139,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
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/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
4 changes: 4 additions & 0 deletions lifecycle/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ func (lcs *LifecycleServicesManager) Client() *jfroghttpclient.JfrogHttpClient {
return lcs.client
}

func (lcs *LifecycleServicesManager) IsDryRun() bool {
return lcs.config.IsDryRun()
}

func (lcs *LifecycleServicesManager) CreateReleaseBundleFromAql(rbDetails lifecycle.ReleaseBundleDetails,
queryParams lifecycle.CommonOptionalQueryParams, signingKeyName string, aqlQuery string) error {
rbService := lifecycle.NewReleaseBundlesService(lcs.config.GetServiceDetails(), lcs.client)
Expand Down
52 changes: 52 additions & 0 deletions tests/releasebundle_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package tests

import (
"github.com/jfrog/jfrog-client-go/artifactory"
artifactoryAuth "github.com/jfrog/jfrog-client-go/artifactory/auth"
"github.com/jfrog/jfrog-client-go/artifactory/services"
"github.com/jfrog/jfrog-client-go/config"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)

func TestImportReleaseBundle(t *testing.T) {
mockServer, rbService := createMockServer(t, func(w http.ResponseWriter, r *http.Request) {
if r.RequestURI == "/"+services.ReleaseBundleImportRestApiEndpoint {
w.WriteHeader(http.StatusBadRequest)
_, err := w.Write([]byte(`
{
"errors" : [ {
"status" : 400,
"message" : "Bundle already exists"
} ]
}
`))
assert.NoError(t, err)
}
})
defer mockServer.Close()
err := rbService.ImportReleaseBundle("releasebundle_test.go")
assert.NoError(t, err)
}

func createMockServer(t *testing.T, testHandler http.HandlerFunc) (*httptest.Server, artifactory.ArtifactoryServicesManager) {
testServer := httptest.NewServer(testHandler)

rtDetails := artifactoryAuth.NewArtifactoryDetails()
rtDetails.SetUrl(testServer.URL + "/")

serviceConfig, err := config.NewConfigBuilder().
SetServiceDetails(rtDetails).
SetDryRun(false).
Build()

if err != nil {
t.Error(err)
}

artService, err := artifactory.New(serviceConfig)
assert.NoError(t, err)
return testServer, artService
}
Loading

0 comments on commit 80b1846

Please sign in to comment.