1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00

fix: Checkmarx project creation (#2112)

* fix : allow creation of Checkmarx projects

* checkmarx: fix project creation

* do not swallow error

* fix preset error handling
This commit is contained in:
Oliver Nocon 2020-10-05 08:16:18 +02:00 committed by GitHub
parent ae213a013e
commit 0fb7ee5488
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 39 deletions

View File

@ -109,8 +109,11 @@ func loadExistingProject(sys checkmarx.System, initialProjectName, pullRequestNa
}
} else {
projects, err := sys.GetProjectsByNameAndTeam(projectName, teamID)
if err != nil || len(projects) == 0 {
return project, projectName, errors.Wrap(err, "no projects found")
if err != nil {
return project, projectName, errors.Wrap(err, "failed getting projects")
}
if len(projects) == 0 {
return checkmarx.Project{}, projectName, nil
}
project = projects[0]
log.Entry().Debugf("Loaded project with name %v", project.Name)
@ -407,24 +410,27 @@ func enforceThresholds(config checkmarxExecuteScanOptions, results map[string]in
}
func createAndConfigureNewProject(sys checkmarx.System, projectName, teamID, presetValue, engineConfiguration string) (checkmarx.Project, error) {
if len(presetValue) == 0 {
log.SetErrorCategory(log.ErrorConfiguration)
return checkmarx.Project{}, fmt.Errorf("preset not specified, creation of project %v failed", projectName)
}
projectCreateResult, err := sys.CreateProject(projectName, teamID)
if err != nil {
return checkmarx.Project{}, errors.Wrapf(err, "cannot create project %v", projectName)
}
if len(presetValue) > 0 {
setPresetForProject(sys, projectCreateResult.ID, projectName, presetValue, engineConfiguration)
} else {
log.SetErrorCategory(log.ErrorConfiguration)
return checkmarx.Project{}, errors.Wrapf(err, "preset not specified, creation of project %v failed", projectName)
if err := setPresetForProject(sys, projectCreateResult.ID, projectName, presetValue, engineConfiguration); err != nil {
return checkmarx.Project{}, errors.Wrapf(err, "failed to set preset %v for project", presetValue)
}
projects, err := sys.GetProjectsByNameAndTeam(projectName, teamID)
if err != nil || len(projects) == 0 {
return checkmarx.Project{}, errors.Wrapf(err, "failed to load newly created project %v", projectName)
}
log.Entry().Debugf("New Project %v created", projectName)
log.Entry().Debugf("Projects: %v", projects)
return projects[0], nil
}
// loadPreset finds a checkmarx.Preset that has either the ID or Name given by presetValue.

View File

@ -232,10 +232,10 @@ func NewSystemInstance(client piperHttp.Uploader, serverURL, username, password
}
func sendRequest(sys *SystemInstance, method, url string, body io.Reader, header http.Header) ([]byte, error) {
return sendRequestInternal(sys, method, url, body, header, "200:399")
return sendRequestInternal(sys, method, url, body, header, []int{})
}
func sendRequestInternal(sys *SystemInstance, method, url string, body io.Reader, header http.Header, validStatusCodeRange string) ([]byte, error) {
func sendRequestInternal(sys *SystemInstance, method, url string, body io.Reader, header http.Header, acceptedErrorCodes []int) ([]byte, error) {
var requestBody io.Reader
var requestBodyCopy io.Reader
if body != nil {
@ -246,37 +246,16 @@ func sendRequestInternal(sys *SystemInstance, method, url string, body io.Reader
defer closer.Close()
}
response, err := sys.client.SendRequest(method, fmt.Sprintf("%v/cxrestapi%v", sys.serverURL, url), requestBody, header, nil)
if err != nil {
if err != nil && !piperutils.ContainsInt(acceptedErrorCodes, response.StatusCode) {
sys.recordRequestDetailsInErrorCase(requestBodyCopy, response)
sys.logger.Errorf("HTTP request failed with error: %s", err)
return nil, err
}
var validResponseCodeList []int
values := strings.Split(validStatusCodeRange, ",")
for _, value := range values {
parts := strings.Split(value, ":")
if len(parts) > 1 {
lower, _ := strconv.Atoi(parts[0])
upper, _ := strconv.Atoi(parts[1])
for i := lower; i <= upper; i++ {
validResponseCodeList = append(validResponseCodeList, i)
}
} else {
validCode, _ := strconv.Atoi(value)
validResponseCodeList = append(validResponseCodeList, validCode)
}
}
if piperutils.ContainsInt(validResponseCodeList, response.StatusCode) {
data, _ := ioutil.ReadAll(response.Body)
sys.logger.Debugf("Valid response body: %v", string(data))
defer response.Body.Close()
return data, nil
}
sys.recordRequestDetailsInErrorCase(requestBodyCopy, response)
sys.logger.Errorf("HTTP request failed with error %s", response.Status)
return nil, errors.Errorf("Invalid HTTP status %v with with code %v received", response.Status, response.StatusCode)
data, _ := ioutil.ReadAll(response.Body)
sys.logger.Debugf("Valid response body: %v", string(data))
defer response.Body.Close()
return data, nil
}
func (sys *SystemInstance) recordRequestDetailsInErrorCase(requestBody io.Reader, response *http.Response) {
@ -359,9 +338,9 @@ func (sys *SystemInstance) GetProjectsByNameAndTeam(projectName, teamID string)
"projectName": {projectName},
"teamId": {teamID},
}
data, err = sendRequestInternal(sys, http.MethodGet, fmt.Sprintf("/projects?%v", body.Encode()), nil, header, "200:399,404")
data, err = sendRequestInternal(sys, http.MethodGet, fmt.Sprintf("/projects?%v", body.Encode()), nil, header, []int{404})
} else {
data, err = sendRequestInternal(sys, http.MethodGet, "/projects", nil, header, "200:399,404")
data, err = sendRequestInternal(sys, http.MethodGet, "/projects", nil, header, []int{404})
}
if err != nil {
return projects, errors.Wrapf(err, "fetching project %v failed", projectName)

View File

@ -40,7 +40,11 @@ func (sm *senderMock) SendRequest(method, url string, body io.Reader, header htt
buf.ReadFrom(body)
sm.requestBody = buf.String()
}
return &http.Response{StatusCode: sm.httpStatusCode, Body: ioutil.NopCloser(strings.NewReader(sm.responseBody))}, nil
var httpError error
if sm.httpStatusCode > 399 {
httpError = fmt.Errorf("http error %v", sm.httpStatusCode)
}
return &http.Response{StatusCode: sm.httpStatusCode, Body: ioutil.NopCloser(strings.NewReader(sm.responseBody))}, httpError
}
func (sm *senderMock) UploadFile(url, file, fieldName string, header http.Header, cookies []*http.Cookie) (*http.Response, error) {
sm.httpMethod = http.MethodPost
@ -95,6 +99,20 @@ func TestSendRequest(t *testing.T) {
})
}
func TestSendRequestInternal(t *testing.T) {
logger := log.Entry().WithField("package", "SAP/jenkins-library/pkg/checkmarx_test")
opts := piperHttp.ClientOptions{}
t.Run("test accepted error", func(t *testing.T) {
myTestClient := senderMock{responseBody: `{"some": "test"}`, httpStatusCode: 404}
sys := SystemInstance{serverURL: "https://cx.server.com", client: &myTestClient, logger: logger}
myTestClient.SetOptions(opts)
_, err := sendRequestInternal(&sys, "GET", "/test", nil, nil, []int{404})
assert.NoError(t, err, "No error expected but error occurred")
})
}
func TestGetOAuthToken(t *testing.T) {
logger := log.Entry().WithField("package", "SAP/jenkins-library/pkg/checkmarx_test")
opts := piperHttp.ClientOptions{}