Skip to content

Commit

Permalink
re-creating client-go api
Browse files Browse the repository at this point in the history
  • Loading branch information
eranturgeman committed Dec 16, 2024
1 parent 96c11f5 commit fffd6df
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 31 deletions.
43 changes: 33 additions & 10 deletions tests/xsc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

func TestXscVersion(t *testing.T) {
initXscTest(t, "")
initXscTest(t, "", "")
version, err := GetXscDetails().GetVersion()
if err != nil {
t.Error(err)
Expand All @@ -16,21 +16,44 @@ func TestXscVersion(t *testing.T) {
}
}

func initXscTest(t *testing.T, minVersion string) {
func initXscTest(t *testing.T, minXscVersion string, minXrayVersion string) {
if !*TestXsc {
t.Skip("Skipping xsc test. To run xsc test add the '-test.xsc=true' option.")
}
validateXscVersion(t, minVersion)
validateXscVersion(t, minXscVersion, minXrayVersion)
}
func validateXscVersion(t *testing.T, minVersion string) {
// Validate active XSC server.
version, err := GetXscDetails().GetVersion()

// This func validates minimal Xsc version.
// Since Xsc was migrated into Xray from version 3.107.13, we need to check minimal Xray version from this version forward instead of Xsc version.
// For features that are available before the migration we pass minXscVersion to check. If the utilized Xray version >= 3.107.13, the returned Xsc version will always suffice the check.
// For features that were introduced only after the migration we pass only minXrayVersion to check and can leave minXscVersion blank.
func validateXscVersion(t *testing.T, minXscVersion string, minXrayVersion string) {
// Validate active Xsc server
currentXscVersion, err := GetXscDetails().GetVersion()
if err != nil {
t.Skip(err)
}
// Validate minimum XSC version.
err = clientUtils.ValidateMinimumVersion(clientUtils.Xsc, version, minVersion)
if err != nil {
t.Skip(err)

if minXscVersion != "" {
// If minXscVersion is provided we assume we have a Xray version BEFORE Xsc migration to it (i.e. prior to 3.107.13)
// In this case we want to validate minimal required Xsc version
err = clientUtils.ValidateMinimumVersion(clientUtils.Xsc, currentXscVersion, minXscVersion)
if err != nil {
t.Skip(err)
}
}

if minXrayVersion != "" {
// If minXrayVersion is provided we assume we have a Xray version AFTER Xsc migration to it (3.107.13+)
// In this case we want to validate minimal required Xray version only
var currentXrayVersion string
currentXrayVersion, err = GetXrayDetails().GetVersion()
if err != nil {
t.Skip(err)
}
err = clientUtils.ValidateMinimumVersion(clientUtils.Xsc, currentXrayVersion, minXrayVersion)
if err != nil {
t.Skip(err)
}
}
}
2 changes: 1 addition & 1 deletion tests/xscanalyticsevent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func isValidUUID(str string) bool {

func initXscEventTest(t *testing.T) (xscDetails auth.ServiceDetails, client *jfroghttpclient.JfrogHttpClient) {
var err error
initXscTest(t, services.AnalyticsMetricsMinXscVersion)
initXscTest(t, services.AnalyticsMetricsMinXscVersion, "")
xscDetails = GetXscDetails()
client, err = jfroghttpclient.JfrogClientBuilder().
SetClientCertPath(xscDetails.GetClientCertPath()).
Expand Down
62 changes: 55 additions & 7 deletions tests/xscconfigprofile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,48 @@ import (
"encoding/json"
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
"github.com/jfrog/jfrog-client-go/xsc/services"
xscutils "github.com/jfrog/jfrog-client-go/xsc/services/utils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"
)

func TestGetConfigurationProfile(t *testing.T) {
initXscTest(t, services.ConfigProfileMinXscVersion)
const configProfileWithoutRepo = "default-test-profile"

mockServer, configProfileService := createXscMockServerForConfigProfile(t)
func TestGetConfigurationProfileByName(t *testing.T) {
initXscTest(t, services.ConfigProfileMinXscVersion, "")

xrayVersion, err := GetXrayDetails().GetVersion()
require.NoError(t, err)

mockServer, configProfileService := createXscMockServerForConfigProfile(t, xrayVersion)
defer mockServer.Close()

configProfile, err := configProfileService.GetConfigurationProfileByName(configProfileWithoutRepo)
assert.NoError(t, err)

profileFileContent, err := os.ReadFile("testdata/configprofile/configProfileExample.json")
assert.NoError(t, err)
var configProfileForComparison services.ConfigProfile
err = json.Unmarshal(profileFileContent, &configProfileForComparison)
assert.NoError(t, err)
assert.Equal(t, &configProfileForComparison, configProfile)
}

func TestGetConfigurationProfileByUrl(t *testing.T) {
initXscTest(t, "", services.ConfigProfileByUrlMinXrayVersion)

xrayVersion, err := GetXrayDetails().GetVersion()
require.NoError(t, err)

mockServer, configProfileService := createXscMockServerForConfigProfile(t, xrayVersion)
defer mockServer.Close()

configProfile, err := configProfileService.GetConfigurationProfile("default-test-profile")
configProfile, err := configProfileService.GetConfigurationProfileByUrl(mockServer.URL)
assert.NoError(t, err)

profileFileContent, err := os.ReadFile("testdata/configprofile/configProfileExample.json")
Expand All @@ -26,17 +54,32 @@ func TestGetConfigurationProfile(t *testing.T) {
err = json.Unmarshal(profileFileContent, &configProfileForComparison)
assert.NoError(t, err)
assert.Equal(t, &configProfileForComparison, configProfile)

}

func createXscMockServerForConfigProfile(t *testing.T) (mockServer *httptest.Server, configProfileService *services.ConfigurationProfileService) {
func createXscMockServerForConfigProfile(t *testing.T, xrayVersion string) (mockServer *httptest.Server, configProfileService *services.ConfigurationProfileService) {
mockServer = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.RequestURI == "/xsc/api/v1/profile/default-test-profile" && r.Method == http.MethodGet {
apiUrlPart := "api/v1/"
var isXrayAfterXscMigration bool
if isXrayAfterXscMigration = xscutils.IsXscXrayInnerService(xrayVersion); isXrayAfterXscMigration {
apiUrlPart = ""
}

switch {
case strings.Contains(r.RequestURI, "/xsc/"+apiUrlPart+"profile/"+configProfileWithoutRepo) && r.Method == http.MethodGet:
w.WriteHeader(http.StatusOK)
content, err := os.ReadFile("testdata/configprofile/configProfileExample.json")
assert.NoError(t, err)
_, err = w.Write(content)
assert.NoError(t, err)
} else {

case strings.Contains(r.RequestURI, "xray/api/v1/xsc/profile_repos") && r.Method == http.MethodPost && isXrayAfterXscMigration:
w.WriteHeader(http.StatusOK)
content, err := os.ReadFile("testdata/configprofile/configProfileExample.json")
assert.NoError(t, err)
_, err = w.Write(content)
assert.NoError(t, err)
default:
assert.Fail(t, "received an unexpected request")
}
}))
Expand All @@ -45,10 +88,15 @@ func createXscMockServerForConfigProfile(t *testing.T) (mockServer *httptest.Ser
xscDetails.SetUrl(mockServer.URL + "/xsc")
xscDetails.SetAccessToken("")

xrayDetails := GetXrayDetails()
xrayDetails.SetUrl(mockServer.URL + "/xray")
xrayDetails.SetAccessToken("")

client, err := jfroghttpclient.JfrogClientBuilder().Build()
assert.NoError(t, err)

configProfileService = services.NewConfigurationProfileService(client)
configProfileService.XscDetails = xscDetails
configProfileService.XrayDetails = xrayDetails
return
}
2 changes: 1 addition & 1 deletion tests/xsclogerrorevent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
const errorMessageContentForTest = "THIS IS NOT A REAL ERROR! This Error is posted as part of TestXscSendLogErrorEvent test"

func TestXscSendLogErrorEvent(t *testing.T) {
initXscTest(t, services.LogErrorMinXscVersion)
initXscTest(t, services.LogErrorMinXscVersion, "")
mockServer, logErrorService := createXscMockServerForLogEvent(t)
defer mockServer.Close()

Expand Down
10 changes: 8 additions & 2 deletions xray/services/xsc/xsc.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,14 @@ func (xs *XscInnerService) GetAnalyticsGeneralEvent(msi string) (*services.XscAn
return eventService.GetGeneralEvent(msi)
}

func (xs *XscInnerService) GetConfigProfile(profileName string) (*services.ConfigProfile, error) {
func (xs *XscInnerService) GetConfigProfileByName(profileName string) (*services.ConfigProfile, error) {
configProfileService := services.NewConfigurationProfileService(xs.client)
configProfileService.XrayDetails = xs.XrayDetails
return configProfileService.GetConfigurationProfile(profileName)
return configProfileService.GetConfigurationProfileByName(profileName)
}

func (xs *XscInnerService) GetConfigProfileByUrl(repoUrl string) (*services.ConfigProfile, error) {
configProfileService := services.NewConfigurationProfileService(xs.client)
configProfileService.XrayDetails = xs.XrayDetails
return configProfileService.GetConfigurationProfileByUrl(repoUrl)
}
9 changes: 7 additions & 2 deletions xsc/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,13 @@ func (sm *XscServicesManager) GetAnalyticsGeneralEvent(msi string) (*services.Xs
return eventService.GetGeneralEvent(msi)
}

func (sm *XscServicesManager) GetConfigProfile(profileName string) (*services.ConfigProfile, error) {
func (sm *XscServicesManager) GetConfigProfileByName(profileName string) (*services.ConfigProfile, error) {
configProfileService := services.NewConfigurationProfileService(sm.client)
configProfileService.XscDetails = sm.config.GetServiceDetails()
return configProfileService.GetConfigurationProfile(profileName)
return configProfileService.GetConfigurationProfileByName(profileName)
}

func (sm *XscServicesManager) GetConfigProfileByUrl(_ string) (*services.ConfigProfile, error) {
// Empty implementation required for alignment with interface
return nil, nil
}
6 changes: 4 additions & 2 deletions xsc/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ type XscService interface {
UpdateAnalyticsGeneralEvent(event services.XscAnalyticsGeneralEventFinalize) error
// GetAnalyticsGeneralEvent returns general event that match the msi provided.
GetAnalyticsGeneralEvent(msi string) (*services.XscAnalyticsGeneralEvent, error)
// GetConfigProfile returns the configuration profile that match the profile name provided.
GetConfigProfile(profileName string) (*services.ConfigProfile, error)
// GetConfigProfileByName returns the configuration profile that match the profile name provided.
GetConfigProfileByName(profileName string) (*services.ConfigProfile, error)
// GetConfigProfileByUrl returns the configuration profile related to the provided repository url.
GetConfigProfileByUrl(profileUrl string) (*services.ConfigProfile, error)
}
44 changes: 38 additions & 6 deletions xsc/services/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ import (

const (
ConfigProfileMinXscVersion = "1.11.0"
xscConfigProfileApi = "profile"
xscDeprecatedConfigProfileApiSuffix = "api/v1/" + xscConfigProfileApi
ConfigProfileByUrlMinXrayVersion = "3.110.0"
xscConfigProfileByNameApi = "profile"
xscConfigProfileByUrlApi = "profile_repos"
xscDeprecatedConfigProfileApiSuffix = "api/v1/" + xscConfigProfileByNameApi
)

type ConfigurationProfileService struct {
Expand Down Expand Up @@ -100,10 +102,10 @@ type ServicesScannerConfig struct {
ExcludePatterns []string `json:"exclude_patterns,omitempty"`
}

func (cp *ConfigurationProfileService) sendConfigProfileRequest(profileName string) (url string, resp *http.Response, body []byte, err error) {
func (cp *ConfigurationProfileService) sendConfigProfileByNameRequest(profileName string) (url string, resp *http.Response, body []byte, err error) {
if cp.XrayDetails != nil {
httpDetails := cp.XrayDetails.CreateHttpClientDetails()
url = fmt.Sprintf("%s%s%s/%s", utils.AddTrailingSlashIfNeeded(cp.XrayDetails.GetUrl()), xscutils.XscInXraySuffix, xscConfigProfileApi, profileName)
url = fmt.Sprintf("%s%s%s/%s", utils.AddTrailingSlashIfNeeded(cp.XrayDetails.GetUrl()), xscutils.XscInXraySuffix, xscConfigProfileByNameApi, profileName)
resp, body, _, err = cp.client.SendGet(url, true, &httpDetails)
return
}
Expand All @@ -114,8 +116,8 @@ func (cp *ConfigurationProfileService) sendConfigProfileRequest(profileName stri
return
}

func (cp *ConfigurationProfileService) GetConfigurationProfile(profileName string) (*ConfigProfile, error) {
url, res, body, err := cp.sendConfigProfileRequest(profileName)
func (cp *ConfigurationProfileService) GetConfigurationProfileByName(profileName string) (*ConfigProfile, error) {
url, res, body, err := cp.sendConfigProfileByNameRequest(profileName)
if err != nil {
return nil, fmt.Errorf("failed to send GET query to '%s': %q", url, err)
}
Expand All @@ -127,3 +129,33 @@ func (cp *ConfigurationProfileService) GetConfigurationProfile(profileName strin
err = errorutils.CheckError(json.Unmarshal(body, &profile))
return &profile, err
}

func (cp *ConfigurationProfileService) sendConfigProfileByUrlRequest(repoUrl string) (url string, resp *http.Response, body []byte, err error) {
if cp.XrayDetails != nil {
httpDetails := cp.XrayDetails.CreateHttpClientDetails()
url = fmt.Sprintf("%s%s%s", utils.AddTrailingSlashIfNeeded(cp.XrayDetails.GetUrl()), xscutils.XscInXraySuffix, xscConfigProfileByUrlApi)
requestContent := []byte(fmt.Sprintf("{\"repo_url\":\"%s\"}", repoUrl))
resp, body, err = cp.client.SendPost(url, requestContent, &httpDetails)
return
}
// Backward compatibility
httpDetails := cp.XscDetails.CreateHttpClientDetails()
url = fmt.Sprintf("%s%s/%s", utils.AddTrailingSlashIfNeeded(cp.XscDetails.GetUrl()), xscDeprecatedConfigProfileApiSuffix, xscConfigProfileByUrlApi)
requestContent := []byte(fmt.Sprintf("{\"repo_url\":\"%s\"}", repoUrl))
resp, body, err = cp.client.SendPost(url, requestContent, &httpDetails)
return
}

func (cp *ConfigurationProfileService) GetConfigurationProfileByUrl(url string) (*ConfigProfile, error) {
url, res, body, err := cp.sendConfigProfileByUrlRequest(url)
if err != nil {
return nil, fmt.Errorf("failed to send POST query to '%s': %q", url, err)
}
if err = errorutils.CheckResponseStatusWithBody(res, body, http.StatusOK); err != nil {
return nil, err
}

var profile ConfigProfile
err = errorutils.CheckError(json.Unmarshal(body, &profile))
return &profile, err
}

0 comments on commit fffd6df

Please sign in to comment.