forked from kyma-project/Cx1ClientGo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreports.go
123 lines (105 loc) · 3.22 KB
/
reports.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package Cx1ClientGo
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"
)
// Reports
func (c Cx1Client) RequestNewReportByID(scanID, projectID, branch, reportType string) (string, error) {
jsonData := map[string]interface{}{
"fileFormat": reportType,
"reportType": "ui",
"reportName": "scan-report",
"data": map[string]interface{}{
"scanId": scanID,
"projectId": projectID,
"branchName": branch,
"sections": []string{
"ScanSummary",
"ExecutiveSummary",
"ScanResults",
},
"scanners": []string{"SAST"},
"host": "",
},
}
jsonBody, err := json.Marshal(jsonData)
if err != nil {
return "", err
}
data, err := c.sendRequest(http.MethodPost, "/reports", bytes.NewReader(jsonBody), nil)
if err != nil {
return "", fmt.Errorf("failed to trigger report generation for scan %v: %s", scanID, err)
}
var reportResponse struct {
ReportId string
}
err = json.Unmarshal([]byte(data), &reportResponse)
return reportResponse.ReportId, err
}
// the v2 report is the "improved scan report" which can be used the same as the existing RequestNewReportByID
// returns the report ID which can be passed to GetReportStatusByID or ReportPollingByID
// supports pdf, csv, and json format (not xml)
func (c Cx1Client) RequestNewReportByIDv2(scanID string, engines []string, format string) (string, error) {
jsonData := map[string]interface{}{
"reportName": "improved-scan-report",
"entities": []map[string]interface{}{
{
"entity": "scan",
"ids": []string{scanID},
"tags": []string{},
},
},
"filters": map[string][]string{
"scanners": engines,
},
"reportType": "ui",
"fileFormat": format,
}
jsonValue, _ := json.Marshal(jsonData)
data, err := c.sendRequest(http.MethodPost, "/reports/v2", bytes.NewReader(jsonValue), nil)
if err != nil {
return "", fmt.Errorf("failed to trigger report v2 generation for scan %v: %s", scanID, err)
} else {
c.logger.Infof("Generating report %v", string(data))
}
var reportResponse struct {
ReportId string
}
err = json.Unmarshal(data, &reportResponse)
return reportResponse.ReportId, err
}
func (c Cx1Client) GetReportStatusByID(reportID string) (ReportStatus, error) {
var response ReportStatus
data, err := c.sendRequest(http.MethodGet, fmt.Sprintf("/reports/%v?returnUrl=true", reportID), nil, nil)
if err != nil {
c.logger.Tracef("Failed to fetch report status for reportID %v: %s", reportID, err)
return response, fmt.Errorf("failed to fetch report status for reportID %v: %s", reportID, err)
}
err = json.Unmarshal([]byte(data), &response)
return response, err
}
func (c Cx1Client) DownloadReport(reportUrl string) ([]byte, error) {
data, err := c.sendRequestInternal(http.MethodGet, reportUrl, nil, nil)
if err != nil {
return []byte{}, fmt.Errorf("failed to download report from url %v: %s", reportUrl, err)
}
return data, nil
}
// convenience
func (c Cx1Client) ReportPollingByID(reportID string) (string, error) {
for {
status, err := c.GetReportStatusByID(reportID)
if err != nil {
return "", err
}
if status.Status == "completed" {
return status.ReportURL, nil
} else if status.Status == "failed" {
return "", fmt.Errorf("report generation failed")
}
time.Sleep(10 * time.Second)
}
}