Skip to content

Commit

Permalink
feat: add report link in summary and analyse command (#34)
Browse files Browse the repository at this point in the history
* link in summary output

* link in verbose output

* link to server

* tests

* review
  • Loading branch information
Deepak Sharma authored Mar 17, 2021
1 parent 72d97f3 commit 5254513
Show file tree
Hide file tree
Showing 11 changed files with 56 additions and 25 deletions.
1 change: 1 addition & 0 deletions analyses/driver/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ type AnalysedDepsType struct {
type GetResponseType struct {
AnalysedDeps []AnalysedDepsType `json:"analyzed_dependencies"`
RegistrationStatus string `json:"registration_status"`
StackID string `json:"external_request_id"`
}

// ReadManifestResponse is arg type of readManifest func
Expand Down
1 change: 1 addition & 0 deletions analyses/stackanalyses/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func (mc *Controller) postRequest(requestParams driver.RequestType, filePath str
Endpoint: APIStackAnalyses,
ThreeScaleToken: requestParams.ThreeScaleToken,
Host: requestParams.Host,
UserID: requestParams.UserID,
}
writer := multipart.NewWriter(manifest)
fd, err := os.Open(filePath)
Expand Down
2 changes: 2 additions & 0 deletions analyses/summary/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func data() driver.GetResponseType {
},
},
},
StackID: "123456789",
}
return *GetResponse
}
Expand All @@ -48,6 +49,7 @@ func TestGetResultSummary(t *testing.T) {
HighVulnerabilities: 0,
MediumVulnerabilities: 1,
LowVulnerabilities: 0,
ReportLink: "https://recommender.api.openshift.io/api/v2/stack-report/123456789",
}
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("Vuln mismatch (-want, +got):\n%s", diff)
Expand Down
5 changes: 4 additions & 1 deletion analyses/summary/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/rs/zerolog/log"

"github.com/fabric8-analytics/cli-tools/analyses/driver"
"github.com/fabric8-analytics/cli-tools/utils"
)

// ProcessSummary processes summary results, return true if Vul found
Expand Down Expand Up @@ -37,6 +38,7 @@ func getResultSummary(analysedResult driver.GetResponseType) *StackSummary {
HighVulnerabilities: data.Severities.High,
MediumVulnerabilities: data.Severities.Medium,
LowVulnerabilities: data.Severities.Low,
ReportLink: utils.BuildReportLink(analysedResult.StackID),
}
return out
}
Expand Down Expand Up @@ -109,11 +111,12 @@ func outputSummaryPlain(result *StackSummary, verboseMsg bool) {
white("Direct Vulnerable Dependencies: "), white(result.DirectVulnerableDependencies), "\n",
white("Total Vulnerabilities: "), white(result.TotalVulnerabilities), "\n",
white("Commonly Known Vulnerabilities: "), white(result.CommonlyKnownVulnerabilities), "\n",
white("Vulnerabilities Unique to Synk: "), white(result.VulnerabilitiesUniqueToSynk), "\n",
white("Vulnerabilities Unique to Snyk: "), white(result.VulnerabilitiesUniqueToSynk), "\n",
red("Critical Vulnerabilities: "), red(result.CriticalVulnerabilities), "\n",
magenta("High Vulnerabilities: "), magenta(result.HighVulnerabilities), "\n",
yellow("Medium Vulnerabilities: "), yellow(result.MediumVulnerabilities), "\n",
blue("Low Vulnerabilities: "), blue(result.LowVulnerabilities), "\n\n",
white("Full Report: "), result.ReportLink, "\n\n",
)
fmt.Fprint(os.Stdout, "(Powered by Snyk)\n\n")
if verboseMsg {
Expand Down
21 changes: 11 additions & 10 deletions analyses/summary/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ type SeverityType struct {

// StackSummary is SA Result Summary output
type StackSummary struct {
TotalScannedDependencies int `json:"total_scanned_dependencies"`
TotalScannedTransitiveDependencies int `json:"total_scanned_transitives"`
TotalVulnerabilities int `json:"total_vulnerabilites"`
CommonlyKnownVulnerabilities int `json:"commonly_known_vulnerabilites"`
VulnerabilitiesUniqueToSynk int `json:"vulnerabilities_unique_to_synk"`
DirectVulnerableDependencies int `json:"direct_vulnerable_dependencies"`
LowVulnerabilities int `json:"low_vulnerabilities"`
MediumVulnerabilities int `json:"medium_vulnerabilities"`
HighVulnerabilities int `json:"high_vulnerabilities"`
CriticalVulnerabilities int `json:"critical_vulnerabilities"`
TotalScannedDependencies int `json:"total_scanned_dependencies"`
TotalScannedTransitiveDependencies int `json:"total_scanned_transitives"`
TotalVulnerabilities int `json:"total_vulnerabilites"`
CommonlyKnownVulnerabilities int `json:"commonly_known_vulnerabilites"`
VulnerabilitiesUniqueToSynk int `json:"vulnerabilities_unique_to_synk"`
DirectVulnerableDependencies int `json:"direct_vulnerable_dependencies"`
LowVulnerabilities int `json:"low_vulnerabilities"`
MediumVulnerabilities int `json:"medium_vulnerabilities"`
HighVulnerabilities int `json:"high_vulnerabilities"`
CriticalVulnerabilities int `json:"critical_vulnerabilities"`
ReportLink string `json:"report_link"`
}

// ProcessVulnerabilities is arg type of processVulnerabilities
Expand Down
3 changes: 3 additions & 0 deletions analyses/verbose/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package verbose
import (
"encoding/json"
"fmt"
"github.com/fabric8-analytics/cli-tools/utils"
"os"
"sort"

Expand Down Expand Up @@ -39,6 +40,7 @@ func getVerboseResult(analysedResult driver.GetResponseType) *StackVerbose {
TotalDirectVulnerabilities: data.TotalDirectVulnerabilities,
TotalTransitiveVulnerabilities: data.TotalTransitiveVulnerabilities,
Severity: data.Severities,
ReportLink: utils.BuildReportLink(analysedResult.StackID),
}
return out
}
Expand Down Expand Up @@ -143,6 +145,7 @@ func outputVerbosePlain(result *StackVerbose) {
)
fmt.Fprintln(os.Stdout, cusColor.Green("Fixable Issues:"))
outputVulDeps(result.Dependencies)
fmt.Fprint(os.Stdout, fmt.Sprintf(cusColor.White("\n\n Full Report: ")+"%s \n\n", result.ReportLink))
fmt.Fprint(os.Stdout, "\n(Powered by Snyk)\n\n")
}

Expand Down
3 changes: 2 additions & 1 deletion analyses/verbose/testdata/getresponse.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@
}
]
}
]
],
"external_request_id": "123456789"
}
3 changes: 2 additions & 1 deletion analyses/verbose/testdata/verbosedata.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@
"critical": [
{"id": "Critical-12345", "severity": "critical", "title": "SQL Attack"}
]
}
},
"report_link": "https://recommender.api.openshift.io/api/v2/stack-report/123456789"
}
1 change: 1 addition & 0 deletions analyses/verbose/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type StackVerbose struct {
TotalTransitives int `json:"total_transitives_scanned"`
TotalTransitiveVulnerabilities int `json:"transitive_vulnerabilities"`
Severity SeverityType `json:"severity"`
ReportLink string `json:"report_link"`
}

// VulnerabilityType type for Vulnerability in verbose output
Expand Down
34 changes: 25 additions & 9 deletions utils/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package utils
import (
"bytes"
"encoding/json"
"fmt"
"mime/multipart"
"net/http"
"net/url"
Expand All @@ -23,29 +24,43 @@ type HTTPRequestType struct {
UserID string `json:"user_id,omitempty"`
}

// BuildReportLink builds stack report UI Link
func BuildReportLink(stackID string) string {
log.Debug().Msgf("Building Report Url.")
APIHost, err := url.Parse(ActualHost)
if err != nil {
log.Fatal().Err(err).Msgf("Unable to Parse Host URL")
}
endpoint := fmt.Sprintf("api/v2/stack-report/%s", stackID)
reportURL := url.URL{Host: APIHost.Hostname(), Path: endpoint}
reportURL.Scheme = "https"
log.Debug().Msgf("Success Building Report Url.")
return reportURL.String()
}

// buildAPIURL builds API Endpoint URL
func buildAPIURL(host string, endpoint string, threeScale string) url.URL {
log.Debug().Msgf("Building API Url.")
APIHost, err := url.Parse(host)
if err != nil {
log.Fatal().Err(err).Msgf("Unable to Parse Host URL")
}
url := url.URL{Host: APIHost.Hostname(), Path: endpoint}
url.Scheme = "https"
q := url.Query()
apiURL := url.URL{Host: APIHost.Hostname(), Path: endpoint}
apiURL.Scheme = "https"
q := apiURL.Query()
q.Set("user_key", threeScale)
url.RawQuery = q.Encode()
apiURL.RawQuery = q.Encode()
log.Debug().Msgf("Success: Building API Url.")
return url
return apiURL
}

// HTTPRequest is generic method for HTTP Requests to server
func HTTPRequest(data HTTPRequestType) *http.Response {
log.Debug().Msgf("Executing HTTPRequest.")
client := &http.Client{}
url := buildAPIURL(data.Host, data.Endpoint, data.ThreeScaleToken)
apiURL := buildAPIURL(data.Host, data.Endpoint, data.ThreeScaleToken)
payload, _ := json.Marshal(&data.Payload)
req, err := http.NewRequest(data.Method, url.String(), bytes.NewBuffer(payload))
req, err := http.NewRequest(data.Method, apiURL.String(), bytes.NewBuffer(payload))
req.Header.Add("Content-Type", "application/json")
req.Header.Add("uuid", data.UserID)

Expand All @@ -64,12 +79,13 @@ func HTTPRequest(data HTTPRequestType) *http.Response {
func HTTPRequestMultipart(data HTTPRequestType, w *multipart.Writer, buf *bytes.Buffer) *http.Response {
log.Debug().Msgf("Executing HTTPRequestMultipart.")
client := &http.Client{}
url := buildAPIURL(data.Host, data.Endpoint, data.ThreeScaleToken)
req, err := http.NewRequest(data.Method, url.String(), buf)
apiURL := buildAPIURL(data.Host, data.Endpoint, data.ThreeScaleToken)
req, err := http.NewRequest(data.Method, apiURL.String(), buf)
if err != nil {
log.Fatal().Err(err).Msgf("Unable to build request")
}
req.Header.Set("Content-Type", w.FormDataContentType())
req.Header.Set("uuid", data.UserID)
res, err := client.Do(req)
if err != nil {
log.Fatal().Err(err).Msgf("Unable to reach the server. hint: Check your Internet connection.")
Expand Down
7 changes: 4 additions & 3 deletions utils/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package utils

// Flag Defaults
const (
Host string = "https://f8a-analytics-2445582058137.production.gw.apicast.io:443"
AuthToken string = "9e7da76708fe374d8c10fa752e72989f"
Debug bool = false
Host string = "https://f8a-analytics-2445582058137.production.gw.apicast.io"
AuthToken string = "9e7da76708fe374d8c10fa752e72989f"
Debug bool = false
ActualHost string = "https://recommender.api.openshift.io"
)

0 comments on commit 5254513

Please sign in to comment.