diff --git a/README.md b/README.md index bb0df362b..953ae9429 100644 --- a/README.md +++ b/README.md @@ -169,13 +169,17 @@ - [Get Violations Report Content](#get-violations-report-content) - [Delete Violations Report](#delete-violations-report) - [Get Artifact Summary](#get-artifact-summary) - - [Get Entitlement info](#get-entitlement-info) - - [XSC APIs](#xsc-apis) - - [Creating XSC Service Manager](#creating-xray-service-manager) + - [Get Entitlement Info](#get-entitlement-info) + - [Create Ignore Rule](#create-ignore-rule) + - [Get Ignore Rule](#get-ignore-rule) + - [Get All Ignore Rules / Query Ignore Rules](#get-all-ignore-rules--query-ignore-rules) + - [Delete Ignore Rule](#delete-ignore-rule) + - [XSC APIs](#xsc-apis) + - [Creating XSC Service Manager](#creating-xsc-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) + - [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) @@ -2260,6 +2264,60 @@ artifactSummary, err := xrayManager.ArtifactSummary(artifactSummaryRequest) isEntitled, err := xrayManager.IsEntitled(featureId) ``` +#### Create Ignore Rule + +```go + rule := services.IgnoreRule{ + Notes: "This is a Test", + ExpiresAt: timePtr(time.Now().Add(time.Hour * 24)), + Filters: services.IgnoreFilters{ + ReleaseBundles: nil, + Builds: nil, + Components: nil, + Artifacts: []services.ArtifactDescriptor{{ + NameVersion: services.NameVersion{ + Name: "docker://test-container", + Version: "v1.2.3", + }, + }}, + Policies: nil, + DockerLayers: nil, + Vulnerabilities: nil, + Licenses: nil, + CVEs: nil, //[]string{"CVE-2023-29404"}, + Watches: nil, + OperationalRisk: nil, + }, + } + ruleId, err := xrayManager.CreateIgnoreRule(rule) +``` + +#### Get Ignore Rule + +```go + rule, err := xrayManager.GetIgnoreRule(ruleId) +``` + +#### Get All Ignore Rules / Query Ignore Rules + +```go + allIgnoreRules, err := xrayManager.GetAllIgnoreRules(nil) + + queriedRules, err := xrayManager.GetAllIgnoreRules(&services.IgnoreRulesGetAllParams{ + ArtifactName: "docker://test-container", + ArtifactVersion: "v1.2.3", + }) +``` + +#### Delete Ignore Rule + +```go + for _, rule := range queriedRules.Data { + err := s.XRayClient.DeleteIgnoreRule(rule.ID) + } + +``` + ## XSC APIs diff --git a/http/jfroghttpclient/client.go b/http/jfroghttpclient/client.go index 52ec2fe7c..2bc0ec94a 100644 --- a/http/jfroghttpclient/client.go +++ b/http/jfroghttpclient/client.go @@ -16,13 +16,14 @@ type JfrogHttpClient struct { preRequestInterceptors []PreRequestInterceptorFunc } -// Implement this function and append it to create an interceptor that will run before sending the request +// PreRequestInterceptorFunc Implement this function and append it to create an interceptor that will run before sending the request type PreRequestInterceptorFunc func(clientDetails *httputils.HttpClientDetails) error func (rtc *JfrogHttpClient) GetHttpClient() *httpclient.HttpClient { return rtc.httpClient } +// SendGet will return error if resp is nil func (rtc *JfrogHttpClient) SendGet(url string, followRedirect bool, httpClientsDetails *httputils.HttpClientDetails) (resp *http.Response, respBody []byte, redirectUrl string, err error) { err = rtc.runPreRequestInterceptors(httpClientsDetails) if err != nil { @@ -31,6 +32,7 @@ func (rtc *JfrogHttpClient) SendGet(url string, followRedirect bool, httpClients return rtc.httpClient.SendGet(url, followRedirect, *httpClientsDetails, "") } +// SendPost will return error if resp is nil func (rtc *JfrogHttpClient) SendPost(url string, content []byte, httpClientsDetails *httputils.HttpClientDetails) (resp *http.Response, body []byte, err error) { err = rtc.runPreRequestInterceptors(httpClientsDetails) if err != nil { @@ -39,6 +41,7 @@ func (rtc *JfrogHttpClient) SendPost(url string, content []byte, httpClientsDeta return rtc.httpClient.SendPost(url, content, *httpClientsDetails, "") } +// SendPostLeaveBodyOpen will return error if resp is nil func (rtc *JfrogHttpClient) SendPostLeaveBodyOpen(url string, content []byte, httpClientsDetails *httputils.HttpClientDetails) (*http.Response, error) { if err := rtc.runPreRequestInterceptors(httpClientsDetails); err != nil { return nil, err @@ -46,11 +49,13 @@ func (rtc *JfrogHttpClient) SendPostLeaveBodyOpen(url string, content []byte, ht return rtc.httpClient.SendPostLeaveBodyOpen(url, content, *httpClientsDetails, "") } +// SendPostForm will return error if resp is nil func (rtc *JfrogHttpClient) SendPostForm(url string, data url.Values, httpClientsDetails *httputils.HttpClientDetails) (resp *http.Response, body []byte, err error) { httpClientsDetails.Headers["Content-Type"] = "application/x-www-form-urlencoded" return rtc.SendPost(url, []byte(data.Encode()), httpClientsDetails) } +// SendPatch will return error if resp is nil func (rtc *JfrogHttpClient) SendPatch(url string, content []byte, httpClientsDetails *httputils.HttpClientDetails) (resp *http.Response, body []byte, err error) { err = rtc.runPreRequestInterceptors(httpClientsDetails) if err != nil { @@ -59,6 +64,7 @@ func (rtc *JfrogHttpClient) SendPatch(url string, content []byte, httpClientsDet return rtc.httpClient.SendPatch(url, content, *httpClientsDetails, "") } +// SendDelete will return error if resp is nil func (rtc *JfrogHttpClient) SendDelete(url string, content []byte, httpClientsDetails *httputils.HttpClientDetails) (resp *http.Response, body []byte, err error) { err = rtc.runPreRequestInterceptors(httpClientsDetails) if err != nil { @@ -67,6 +73,7 @@ func (rtc *JfrogHttpClient) SendDelete(url string, content []byte, httpClientsDe return rtc.httpClient.SendDelete(url, content, *httpClientsDetails, "") } +// SendHead will return error if resp is nil func (rtc *JfrogHttpClient) SendHead(url string, httpClientsDetails *httputils.HttpClientDetails) (resp *http.Response, body []byte, err error) { err = rtc.runPreRequestInterceptors(httpClientsDetails) if err != nil { @@ -75,6 +82,7 @@ func (rtc *JfrogHttpClient) SendHead(url string, httpClientsDetails *httputils.H return rtc.httpClient.SendHead(url, *httpClientsDetails, "") } +// SendPut will return error if resp is nil func (rtc *JfrogHttpClient) SendPut(url string, content []byte, httpClientsDetails *httputils.HttpClientDetails) (resp *http.Response, body []byte, err error) { err = rtc.runPreRequestInterceptors(httpClientsDetails) if err != nil { @@ -83,6 +91,7 @@ func (rtc *JfrogHttpClient) SendPut(url string, content []byte, httpClientsDetai return rtc.httpClient.SendPut(url, content, *httpClientsDetails, "") } +// Send will return error if resp is nil func (rtc *JfrogHttpClient) Send(method string, url string, content []byte, followRedirect bool, closeBody bool, httpClientsDetails *httputils.HttpClientDetails, logMsgPrefix string) (resp *http.Response, respBody []byte, redirectUrl string, err error) { err = rtc.runPreRequestInterceptors(httpClientsDetails) diff --git a/xray/manager.go b/xray/manager.go index d1eb6eca8..c715b6acb 100644 --- a/xray/manager.go +++ b/xray/manager.go @@ -157,7 +157,7 @@ func (sm *XrayServicesManager) GenerateLicensesReport(params services.LicensesRe return reportService.Licenses(params) } -// GenerateVoilationsReport returns a Xray report response of the requested report +// GenerateViolationsReport returns a Xray report response of the requested report func (sm *XrayServicesManager) GenerateViolationsReport(params services.ViolationsReportRequestParams) (resp *services.ReportResponse, err error) { reportService := services.NewReportService(sm.client) reportService.XrayDetails = sm.config.GetServiceDetails() @@ -198,3 +198,27 @@ func (sm *XrayServicesManager) IsEntitled(featureId string) (bool, error) { entitlementsService.XrayDetails = sm.config.GetServiceDetails() return entitlementsService.IsEntitled(featureId) } + +func (sm *XrayServicesManager) CreateIgnoreRule(rule services.IgnoreRule) (string, error) { + ignoreRuleService := services.NewIgnoreRulesService(sm.client) + ignoreRuleService.XrayDetails = sm.config.GetServiceDetails() + return ignoreRuleService.Create(rule) +} + +func (sm *XrayServicesManager) DeleteIgnoreRule(ruleId string) error { + ignoreRuleService := services.NewIgnoreRulesService(sm.client) + ignoreRuleService.XrayDetails = sm.config.GetServiceDetails() + return ignoreRuleService.Delete(ruleId) +} + +func (sm *XrayServicesManager) GetIgnoreRule(ruleId string) (*services.IgnoreRuleDetail, error) { + ignoreRuleService := services.NewIgnoreRulesService(sm.client) + ignoreRuleService.XrayDetails = sm.config.GetServiceDetails() + return ignoreRuleService.Get(ruleId) +} + +func (sm *XrayServicesManager) GetAllIgnoreRules(params *services.IgnoreRulesGetAllParams) (*services.IgnoreRuleResponse, error) { + ignoreRuleService := services.NewIgnoreRulesService(sm.client) + ignoreRuleService.XrayDetails = sm.config.GetServiceDetails() + return ignoreRuleService.GetAll(params) +} diff --git a/xray/services/ignore_rules.go b/xray/services/ignore_rules.go new file mode 100644 index 000000000..162aadaf0 --- /dev/null +++ b/xray/services/ignore_rules.go @@ -0,0 +1,327 @@ +package services + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "regexp" + "time" + + artUtils "github.com/jfrog/jfrog-client-go/artifactory/services/utils" + "github.com/jfrog/jfrog-client-go/auth" + "github.com/jfrog/jfrog-client-go/http/jfroghttpclient" + clientUtils "github.com/jfrog/jfrog-client-go/utils" + "github.com/jfrog/jfrog-client-go/utils/errorutils" + "github.com/jfrog/jfrog-client-go/utils/log" +) + +const ( + ignoreRulesUrl = "api/v1/ignore_rules" + uuidRegEx = "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" + minXrayIgnoreRulesVersion = "3.11" +) + +// IgnoreRulesService defines the http client and Xray details +type IgnoreRulesService struct { + client *jfroghttpclient.JfrogHttpClient + XrayDetails auth.ServiceDetails +} + +type IgnoreRuleNotFoundError struct { + InnerError error +} + +func (e IgnoreRuleNotFoundError) Error() string { + innerErrorText := "" + if e.InnerError != nil { + innerErrorText = e.InnerError.Error() + } + return fmt.Sprintf("Xray: ignore rule not found. %s", innerErrorText) +} + +// NewIgnoreRulesService creates a new Xray Policy Service +func NewIgnoreRulesService(client *jfroghttpclient.JfrogHttpClient) *IgnoreRulesService { + return &IgnoreRulesService{client: client} +} + +// GetXrayDetails returns the Xray details +func (irs *IgnoreRulesService) GetXrayDetails() auth.ServiceDetails { + return irs.XrayDetails +} + +// GetJfrogHttpClient returns the http client +func (irs *IgnoreRulesService) GetJfrogHttpClient() *jfroghttpclient.JfrogHttpClient { + return irs.client +} + +func (irs *IgnoreRulesService) CheckMinimumVersion() error { + xrDetails := irs.GetXrayDetails() + if xrDetails == nil { + return errorutils.CheckErrorf("Xray details not configured.") + } + version, err := xrDetails.GetVersion() + if err != nil { + return fmt.Errorf("couldn't get Xray version. Error: %w", err) + } + + return clientUtils.ValidateMinimumVersion(clientUtils.Xray, version, minXrayIgnoreRulesVersion) +} + +func (irs *IgnoreRulesService) getIgnoreRulesURL() string { + return fmt.Sprintf("%s%s", irs.XrayDetails.GetUrl(), ignoreRulesUrl) +} + +// Delete will delete an existing ignore rule by ruleId +// It will error if no ignore rule can be found by that ruleId. +func (irs *IgnoreRulesService) Delete(ruleId string) error { + if err := irs.CheckMinimumVersion(); err != nil { + return err + } + httpClientsDetails := irs.XrayDetails.CreateHttpClientDetails() + artUtils.SetContentType("application/json", &httpClientsDetails.Headers) + + resp, body, err := irs.client.SendDelete(irs.getRuleIdUrl(ruleId), nil, &httpClientsDetails) + if err != nil { + return err + } + if err = errorutils.CheckResponseStatusWithBody(resp, body, http.StatusNoContent); err != nil { + if resp != nil && resp.StatusCode == http.StatusNotFound { + notFound := IgnoreRuleNotFoundError{InnerError: err} + return notFound + } + return err + } + return nil +} + +// Create will create a new Xray ignore rule +func (irs *IgnoreRulesService) Create(ignoreRule IgnoreRule) (string, error) { + if err := irs.CheckMinimumVersion(); err != nil { + return "", err + } + content, err := json.Marshal(ignoreRule) + if err != nil { + return "", errorutils.CheckErrorf("error unmarshalling ignore rule %w", err) + } + + httpClientsDetails := irs.XrayDetails.CreateHttpClientDetails() + artUtils.SetContentType("application/json", &httpClientsDetails.Headers) + + resp, body, err := irs.client.SendPost(irs.getIgnoreRulesURL(), content, &httpClientsDetails) + if err != nil { + return "", err + } + if resp != nil { + log.Debug("Xray response:", resp.Status) + } + if err = errorutils.CheckResponseStatusWithBody(resp, body, http.StatusCreated); err != nil { + return "", err + } + responseBody := struct { + Info string `json:"info"` + }{} + if err = json.Unmarshal(body, &responseBody); err != nil { + return "", errorutils.CheckError(err) + } + uuid := regexp.MustCompile(uuidRegEx).FindString(responseBody.Info) + + return uuid, nil +} + +// Get retrieves the details about an Xray ignore rule by its id +// It will error if no policy can be found by that name. +func (irs *IgnoreRulesService) Get(ruleId string) (ignoreRule *IgnoreRuleDetail, err error) { + if err = irs.CheckMinimumVersion(); err != nil { + return nil, err + } + httpClientsDetails := irs.XrayDetails.CreateHttpClientDetails() + resp, body, _, err := irs.client.SendGet(irs.getRuleIdUrl(ruleId), true, &httpClientsDetails) + ignoreRule = &IgnoreRuleDetail{} + if err != nil { + return nil, err + } + log.Debug("Xray response:", resp.Status) + if err = errorutils.CheckResponseStatusWithBody(resp, body, http.StatusOK); err != nil { + return nil, err + } + + err = json.Unmarshal(body, ignoreRule) + if err != nil { + return nil, errors.New("failed unmarshalling ignore rules " + ruleId) + } + + return ignoreRule, nil +} + +// GetAll retrieves the details about all Xray ignore rules that match the given parameters +func (irs *IgnoreRulesService) GetAll(params *IgnoreRulesGetAllParams) (ignoreRules *IgnoreRuleResponse, err error) { + if err = irs.CheckMinimumVersion(); err != nil { + return nil, err + } + httpClientsDetails := irs.XrayDetails.CreateHttpClientDetails() + url, err := clientUtils.BuildUrl(irs.XrayDetails.GetUrl(), ignoreRulesUrl, params.getParamMap()) + if err != nil { + return nil, err + } + resp, body, _, err := irs.client.SendGet(url, true, &httpClientsDetails) + ignoreRules = &IgnoreRuleResponse{} + if err != nil { + return nil, err + } + log.Debug("Xray response:", resp.Status) + if err = errorutils.CheckResponseStatusWithBody(resp, body, http.StatusOK); err != nil { + return nil, err + } + err = json.Unmarshal(body, ignoreRules) + if err != nil { + return nil, errors.New("failed unmarshalling ignoreRules") + } + + return ignoreRules, nil +} + +func (irs *IgnoreRulesService) getRuleIdUrl(ruleId string) string { + return fmt.Sprintf("%s/%s", irs.getIgnoreRulesURL(), ruleId) +} + +func (p *IgnoreRulesGetAllParams) getParamMap() map[string]string { + params := make(map[string]string) + if p == nil { + return params + } + if p.Vulnerability != "" { + params["vulnerability"] = p.Vulnerability + } + if p.License != "" { + params["license"] = p.License + } + if p.Policy != "" { + params["policy"] = p.Policy + } + if p.Watch != "" { + params["watch"] = p.Watch + } + if p.ComponentName != "" { + params["component_name"] = p.ComponentName + } + if p.ComponentVersion != "" { + params["component_version"] = p.ComponentVersion + } + if p.ArtifactName != "" { + params["artifact_name"] = p.ArtifactName + } + if p.ArtifactVersion != "" { + params["artifact_version"] = p.ArtifactVersion + } + if p.BuildName != "" { + params["build_name"] = p.BuildName + } + if p.BuildVersion != "" { + params["build_version"] = p.BuildVersion + } + if p.ReleaseBundleName != "" { + params["release_bundle_name"] = p.ReleaseBundleName + } + if p.ReleaseBundleVersion != "" { + params["release_bundle_version"] = p.ReleaseBundleVersion + } + if p.DockerLayer != "" { + params["docker_layer"] = p.DockerLayer + } + if p.OrderBy != "" { + params["order_by"] = p.OrderBy + } + if p.Direction != "" { + params["direction"] = p.Direction + } + if p.PageNum != 0 { + params["page_num"] = fmt.Sprintf("%d", p.PageNum) + } + if p.NumOfRows != 0 { + params["num_of_rows"] = fmt.Sprintf("%d", p.NumOfRows) + } + if !p.ExpiresBefore.IsZero() { + params["expires_before"] = p.ExpiresBefore.UTC().Format(time.RFC3339) + } + if !p.ExpiresAfter.IsZero() { + params["expires_after"] = p.ExpiresAfter.UTC().Format(time.RFC3339) + } + if p.ProjectKey != "" { + params["project_key"] = p.ProjectKey + } + + return params +} + +// IgnoreRuleResponse struct representing the entire JSON +type IgnoreRuleResponse struct { + Data []IgnoreRuleDetail `json:"data"` + TotalCount int `json:"total_count"` +} + +// IgnoreRule struct representing an Ignore Rule +type IgnoreRule struct { + Notes string `json:"notes"` + ExpiresAt *time.Time `json:"expires_at,omitempty"` + Filters IgnoreFilters `json:"ignore_filters"` +} + +// IgnoreRuleDetail struct representing an Ignore Rule as returned by the API +type IgnoreRuleDetail struct { + IgnoreRule + ID string `json:"id"` + Author string `json:"author"` + Created time.Time `json:"created"` + IsExpired bool `json:"is_expired"` +} + +// IgnoreFilters struct representing the "ignore_filters" object +type IgnoreFilters struct { + ReleaseBundles []NameVersion `json:"release_bundles,omitempty"` + Builds []NameVersion `json:"builds,omitempty"` + Components []NameVersion `json:"components,omitempty"` + Artifacts []ArtifactDescriptor `json:"artifacts,omitempty"` + Policies []string `json:"policies,omitempty"` + DockerLayers []string `json:"docker_layers,omitempty"` + Vulnerabilities []string `json:"vulnerabilities,omitempty"` + Licenses []string `json:"licenses,omitempty"` + CVEs []string `json:"cves,omitempty"` + Watches []string `json:"watches,omitempty"` + OperationalRisk []string `json:"operational_risk,omitempty"` +} + +// NameVersion struct representing items with a Name / Version combo +type NameVersion struct { + Name string `json:"name"` + Version string `json:"version"` +} + +// ArtifactDescriptor struct representing each item in the "artifacts" array +type ArtifactDescriptor struct { + NameVersion + Path string `json:"path"` +} + +type IgnoreRulesGetAllParams struct { + Vulnerability string `json:"vulnerability"` + License string `json:"license"` + Policy string `json:"policy"` + Watch string `json:"watch"` + ComponentName string `json:"component_name"` + ComponentVersion string `json:"component_version"` + ArtifactName string `json:"artifact_name"` + ArtifactVersion string `json:"artifact_version"` + BuildName string `json:"build_name"` + BuildVersion string `json:"build_version"` + ReleaseBundleName string `json:"release_bundle_name"` + ReleaseBundleVersion string `json:"release_bundle_version"` + DockerLayer string `json:"docker_layer"` + ExpiresBefore time.Time `json:"expires_before"` + ExpiresAfter time.Time `json:"expires_after"` + ProjectKey string `json:"project_key"` + OrderBy string `json:"order_by"` + Direction string `json:"direction"` + PageNum int `json:"page_num"` + NumOfRows int `json:"num_of_rows"` +} diff --git a/xray/services/ignore_rules_test.go b/xray/services/ignore_rules_test.go new file mode 100644 index 000000000..850133448 --- /dev/null +++ b/xray/services/ignore_rules_test.go @@ -0,0 +1,310 @@ +package services + +import ( + "fmt" + "testing" + "time" + + "github.com/jfrog/jfrog-client-go/auth" + "github.com/jfrog/jfrog-client-go/http/jfroghttpclient" + "github.com/jfrog/jfrog-client-go/utils/io/httputils" + "github.com/stretchr/testify/assert" +) + +func TestNewIgnoreRulesService(t *testing.T) { + httpClient := &jfroghttpclient.JfrogHttpClient{} + service := NewIgnoreRulesService(httpClient) + assert.NotNil(t, service) + assert.Equal(t, httpClient, service.client) +} + +func TestCheckMinimumVersion(t *testing.T) { + // Mock XrayDetails + xrDetails := &mockServiceDetails{} + + // Mock IgnoreRulesService with mocked XrayDetails + service := &IgnoreRulesService{ + XrayDetails: xrDetails, + } + + // Test case: Xray version above minimum required + xrDetails.version = "3.11.1" + err := service.CheckMinimumVersion() + assert.NoError(t, err) + + // Test case: Xray version below minimum required + xrDetails.version = "3.10.9" + err = service.CheckMinimumVersion() + assert.Error(t, err) + + // Test case: Missing XrayDetails + service.XrayDetails = nil + err = service.CheckMinimumVersion() + assert.Error(t, err) +} + +func TestGetIgnoreRulesURL(t *testing.T) { + // Mock IgnoreRulesService with mocked XrayDetails + service := &IgnoreRulesService{ + XrayDetails: &mockServiceDetails{}, + } + + expectedURL := "http://example.com/api/v1/ignore_rules" + assert.Equal(t, expectedURL, service.getIgnoreRulesURL()) +} + +func TestGetRuleIdUrl(t *testing.T) { + // Mock IgnoreRulesService with mocked XrayDetails + service := &IgnoreRulesService{ + XrayDetails: &mockServiceDetails{}, + } + + expectedURL := "http://example.com/api/v1/ignore_rules/ruleId" + assert.Equal(t, expectedURL, service.getRuleIdUrl("ruleId")) +} + +func TestGetParamMap(t *testing.T) { + now := time.Now() + params := &IgnoreRulesGetAllParams{ + Vulnerability: "vuln", + License: "lic", + Policy: "pol", + Watch: "watch", + ComponentName: "compName", + ComponentVersion: "compVer", + ArtifactName: "artName", + ArtifactVersion: "artVer", + BuildName: "buildName", + BuildVersion: "buildVer", + ReleaseBundleName: "rbName", + ReleaseBundleVersion: "rbVer", + DockerLayer: "dockerLayer", + OrderBy: "order", + Direction: "dir", + PageNum: 1, + NumOfRows: 10, + ExpiresBefore: now, + ExpiresAfter: now, + ProjectKey: "projKey", + } + paramMap := params.getParamMap() + assert.NotNil(t, paramMap) + assert.Equal(t, paramMap["vulnerability"], params.Vulnerability) + + assert.Equal(t, paramMap["license"], params.License) + + assert.Equal(t, paramMap["policy"], params.Policy) + + assert.Equal(t, paramMap["watch"], params.Watch) + + assert.Equal(t, paramMap["component_name"], params.ComponentName) + + assert.Equal(t, paramMap["component_version"], params.ComponentVersion) + + assert.Equal(t, paramMap["artifact_name"], params.ArtifactName) + + assert.Equal(t, paramMap["artifact_version"], params.ArtifactVersion) + + assert.Equal(t, paramMap["build_name"], params.BuildName) + + assert.Equal(t, paramMap["build_version"], params.BuildVersion) + + assert.Equal(t, paramMap["release_bundle_name"], params.ReleaseBundleName) + + assert.Equal(t, paramMap["release_bundle_version"], params.ReleaseBundleVersion) + + assert.Equal(t, paramMap["docker_layer"], params.DockerLayer) + + assert.Equal(t, paramMap["order_by"], params.OrderBy) + + assert.Equal(t, paramMap["direction"], params.Direction) + + assert.Equal(t, paramMap["page_num"], fmt.Sprintf("%d", params.PageNum)) + + assert.Equal(t, paramMap["num_of_rows"], fmt.Sprintf("%d", params.NumOfRows)) + + assert.Equal(t, paramMap["expires_before"], params.ExpiresBefore.UTC().Format(time.RFC3339)) + + assert.Equal(t, paramMap["expires_after"], params.ExpiresAfter.UTC().Format(time.RFC3339)) + + assert.Equal(t, paramMap["project_key"], params.ProjectKey) + +} + +// Mock implementation of auth.ServiceDetails +type mockServiceDetails struct { + version string +} + +func (m *mockServiceDetails) GetUser() string { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) GetPassword() string { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) GetApiKey() string { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) GetAccessToken() string { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) GetPreRequestFunctions() []auth.ServiceDetailsPreRequestFunc { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) GetClientCertPath() string { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) GetClientCertKeyPath() string { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) GetSshUrl() string { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) GetSshKeyPath() string { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) GetSshPassphrase() string { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) GetSshAuthHeaders() map[string]string { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) GetClient() *jfroghttpclient.JfrogHttpClient { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetUrl(url string) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetUser(user string) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetPassword(password string) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetApiKey(apiKey string) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetAccessToken(accessToken string) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) AppendPreRequestFunction(requestFunc auth.ServiceDetailsPreRequestFunc) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetClientCertPath(certificatePath string) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetClientCertKeyPath(certificatePath string) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetSshUrl(url string) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetSshKeyPath(sshKeyPath string) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetSshPassphrase(sshPassphrase string) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetSshAuthHeaders(sshAuthHeaders map[string]string) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetClient(client *jfroghttpclient.JfrogHttpClient) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetDialTimeout(dialTimeout time.Duration) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) SetOverallRequestTimeout(overallRequestTimeout time.Duration) { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) IsSshAuthHeaderSet() bool { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) IsSshAuthentication() bool { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) AuthenticateSsh(sshKey, sshPassphrase string) error { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) InitSsh() error { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) RunPreRequestFunctions(httpClientDetails *httputils.HttpClientDetails) error { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) CreateHttpClientDetails() httputils.HttpClientDetails { + //TODO implement me + panic("implement me") +} + +func (m *mockServiceDetails) GetVersion() (string, error) { + return m.version, nil +} + +func (m *mockServiceDetails) GetUrl() string { + return "http://example.com/" +} diff --git a/xray/services/report.go b/xray/services/report.go index ee387f8ed..589cc30ca 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 (