Skip to content

Commit

Permalink
Add report and license command
Browse files Browse the repository at this point in the history
  • Loading branch information
viktigpetterr committed May 13, 2022
1 parent 0001d33 commit e53c265
Show file tree
Hide file tree
Showing 14 changed files with 268 additions and 32 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/debricked.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
name: Debricked Automations

on: [push, pull_request]
on:
push:
branches:
- main
pull_request:

jobs:
vulnerabilities-scan:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ jobs:

- name: Test coverage
run: bash scripts/check_coverage.sh
if: always()
env:
TEST_COVERAGE_THRESHOLD: 90

Expand Down
4 changes: 2 additions & 2 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ func (debClient *DebClient) Post(uri string, contentType string, body *bytes.Buf
}

// Get makes a GET request to one of Debricked's API endpoints
func (debClient *DebClient) Get(uri string) (*http.Response, error) {
return get(uri, debClient, true)
func (debClient *DebClient) Get(uri string, format string) (*http.Response, error) {
return get(uri, debClient, true, format)
}
4 changes: 2 additions & 2 deletions pkg/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func TestNewDebClientWithWithURI(t *testing.T) {

func TestClientUnauthorized(t *testing.T) {
setUp(false)
_, err := client.Get("/api/1.0/open/user-profile/is-admin")
_, err := client.Get("/api/1.0/open/user-profile/is-admin", "application/json")
if err == nil {
t.Error("failed to assert client error")
}
Expand All @@ -91,7 +91,7 @@ func TestClientUnauthorized(t *testing.T) {

func TestGet(t *testing.T) {
setUp(true)
res, err := client.Get("/api/1.0/open/user-profile/is-admin")
res, err := client.Get("/api/1.0/open/user-profile/is-admin", "application/json")
if err != nil {
t.Fatal("failed to assert that no client error occurred. Error: ", err.Error())
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/client/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ import (
"net/http"
)

func get(uri string, debClient *DebClient, retry bool) (*http.Response, error) {
request, err := newRequest("GET", *debClient.host+uri, debClient.jwtToken, nil)
func get(uri string, debClient *DebClient, retry bool, format string) (*http.Response, error) {
request, err := newRequest("GET", *debClient.host+uri, debClient.jwtToken, format, nil)
if err != nil {
return nil, err
}
res, _ := debClient.httpClient.Do(request)
req := func() (*http.Response, error) {
return get(uri, debClient, false)
return get(uri, debClient, false, format)
}

return interpret(res, req, debClient, retry)
}

func post(uri string, debClient *DebClient, contentType string, body *bytes.Buffer, retry bool) (*http.Response, error) {
request, err := newRequest("POST", *debClient.host+uri, debClient.jwtToken, body)
request, err := newRequest("POST", *debClient.host+uri, debClient.jwtToken, "application/json", body)
if err != nil {
return nil, err
}
Expand All @@ -40,12 +40,12 @@ func post(uri string, debClient *DebClient, contentType string, body *bytes.Buff
}

// newRequest creates a new HTTP request with necessary headers added
func newRequest(method string, url string, jwtToken string, body io.Reader) (*http.Request, error) {
func newRequest(method string, url string, jwtToken string, format string, body io.Reader) (*http.Request, error) {
req, err := http.NewRequest(method, url, body)
if err != nil {
return nil, err
}
req.Header.Add("Accept", `application/json`)
req.Header.Add("Accept", format)
req.Header.Add("Authorization", "Bearer "+jwtToken)

return req, nil
Expand Down
36 changes: 36 additions & 0 deletions pkg/cmd/check/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ package check

import (
"debricked/pkg/client"
"encoding/json"
"errors"
"fmt"
"github.com/spf13/cobra"
"io"
"log"
"net/http"
)

var debClient *client.DebClient
Expand Down Expand Up @@ -32,3 +37,34 @@ func check(hash string) error {

return nil
}

type latestScan struct {
Id *int `json:"id"`
Date *int `json:"date"`
Url *string `json:"commitUrl"`
}

func getScanId(commitId int) (int, error) {
uri := fmt.Sprintf("/api/1.0/open/scan/latest-scan-status?commitId=%d", commitId)
res, err := debClient.Get(uri, "application/json")
if err != nil {
return 0, err
}

if res.StatusCode != http.StatusOK {
return 0, errors.New(fmt.Sprintf("No scan was found for commit"))
}

body, err := io.ReadAll(res.Body)
var scan map[string]latestScan
err = json.Unmarshal(body, &scan)
if err != nil {
return 0, err
}
id := scan["latestScan"].Id
if id == nil {
return 0, errors.New(fmt.Sprintf("No scan was found for commit"))
}

return *id, err
}
105 changes: 105 additions & 0 deletions pkg/cmd/report/license/license.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package license

import (
"debricked/pkg/client"
"encoding/json"
"errors"
"fmt"
"github.com/fatih/color"
"github.com/spf13/cobra"
"io"
"net/http"
)

var debClient *client.DebClient

var email string
var commitHash string

func NewLicenseCmd(debrickedClient *client.DebClient) *cobra.Command {
debClient = debrickedClient
cmd := &cobra.Command{
Use: "license",
Short: "Generate license report",
Long: `Generate license report from a commit hash.
This is a premium feature. Please visit https://debricked.com/pricing/ for more info.
The finished report will be sent to the specified email address.`,
RunE: run,
}

cmd.Flags().StringVarP(&email, "email", "e", "", "The email address that the report will be sent to")
_ = cmd.MarkFlagRequired("email")

cmd.Flags().StringVarP(&commitHash, "commit", "c", "", "commit hash")
_ = cmd.MarkFlagRequired("commit")

return cmd
}

func run(_ *cobra.Command, _ []string) error {
if err := report(); err != nil {
return errors.New(fmt.Sprintf("%s %s\n", color.RedString("⨯"), err.Error()))
}

fmt.Printf("%s Successfully ordered license report\n", color.GreenString("✔"))

return nil
}

func report() error {
commitId, err := getCommitId(commitHash)
if err != nil {
return err
}

return orderReport(commitId)
}

func orderReport(commitId int) error {
uri := fmt.Sprintf("/api/1.0/open/licenses/get-licenses?order=asc&sortColumn=name&generateExcel=1&commitId=%d&email=%s", commitId, email)
res, err := debClient.Get(uri, "application/json")
if err != nil {
return err
}
if res.StatusCode == http.StatusForbidden {
return errors.New("premium feature. Please visit https://debricked.com/pricing/ for more info")
}

if res.StatusCode != http.StatusOK {
return errors.New(fmt.Sprintf("failed to order report. Status code: %d", res.StatusCode))
}

return nil
}

type commit struct {
FileIds []int `json:"uploaded_programs_file_ids"`
Id int `json:"id"`
Name string `json:"name"`
ReleaseData string `json:"release_date"`
}

func getCommitId(hash string) (int, error) {
uri := fmt.Sprintf("/api/1.0/releases/by/name?name=%s", hash)
res, err := debClient.Get(uri, "application/json")
if err != nil {
return 0, err
}

if res.StatusCode == http.StatusForbidden {
return 0, errors.New("premium feature. Please visit https://debricked.com/pricing/ for more info")
}

if res.StatusCode != http.StatusOK {
return 0, errors.New(fmt.Sprintf("No commit was found with the name %s", hash))
}

body, err := io.ReadAll(res.Body)
var commits []commit
err = json.Unmarshal(body, &commits)
if len(commits) == 0 {
return 0, errors.New(fmt.Sprintf("No commit was found with the name %s", hash))
}

return commits[0].Id, err
}
82 changes: 82 additions & 0 deletions pkg/cmd/report/license/license_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package license

import (
"debricked/pkg/client"
"fmt"
"strings"
"testing"
)

const validCommit = "84cac1be9931f8bcc8ef59c5544aaac8c5c97c8b"

func TestNewLicenseCmd(t *testing.T) {
cmd := NewLicenseCmd(client.NewDebClient(nil))
commands := cmd.Commands()
nbrOfCommands := 0
if len(commands) != nbrOfCommands {
t.Error(fmt.Sprintf("failed to assert that there were %d sub commands connected", nbrOfCommands))
}

flags := cmd.Flags()
flagAssertions := map[string]string{
"commit": "c",
"email": "e",
}
for name, shorthand := range flagAssertions {
flag := flags.Lookup(name)
if flag == nil {
t.Error(fmt.Sprintf("failed to assert that %s flag was set", name))
}
if flag.Shorthand != shorthand {
t.Error(fmt.Sprintf("failed to assert that %s flag shorthand %s was set correctly", name, shorthand))
}
}
}

func TestRunUnAuthorized(t *testing.T) {
email = "[email protected]"
commitHash = validCommit
accessToken := "invalid"
debClient = client.NewDebClient(&accessToken)
err := run(nil, nil)
if err == nil {
t.Fatal("failed to assert that an error occurred")
}
if !strings.Contains(err.Error(), "⨯ Unauthorized. Specify access token") {
t.Error("failed to assert error message")
}
}

func TestRun(t *testing.T) {
email = "[email protected]"
commitHash = validCommit
debClient = client.NewDebClient(nil)
err := run(nil, nil)
if err != nil {
t.Fatal("failed to assert that no error occurred")
}
}

func TestReportInvalidCommitHash(t *testing.T) {
email = "[email protected]"
commitHash = "invalid"
debClient = client.NewDebClient(nil)
err := report()
if err == nil {
t.Fatal("failed to assert that error occurred")
}
if !strings.Contains(err.Error(), "No commit was found with the name invalid") {
t.Error("failed to assert error message")
}
}

func TestGetCommitId(t *testing.T) {
debClient = client.NewDebClient(nil)
id, err := getCommitId(validCommit)
if err != nil {
t.Fatal("failed to assert that no error occurred")
}
if id < 1 {
t.Error("failed to assert that the commit ID was a positive integer")
}
}
25 changes: 9 additions & 16 deletions pkg/cmd/report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,22 @@ package report

import (
"debricked/pkg/client"
"fmt"
"debricked/pkg/cmd/report/license"
"github.com/spf13/cobra"
"log"
)

var debClient *client.DebClient

func Report() error {
fmt.Println("Reporting!")
return nil
}

func NewReportCmd(debrickedClient *client.DebClient) *cobra.Command {
debClient = debrickedClient
return &cobra.Command{
cmd := &cobra.Command{
Use: "report",
Short: "Generate license report for upload ID",
Long: "Generate license report for upload ID",
Run: func(cmd *cobra.Command, args []string) {
err := Report()
if err != nil {
log.Fatal(err)
}
},
Short: "Generate reports",
Long: `Generate reports for a commit.
This is a premium feature. Please visit https://debricked.com/pricing/ for more info.`,
}

cmd.AddCommand(license.NewLicenseCmd(debClient))

return cmd
}
15 changes: 15 additions & 0 deletions pkg/cmd/report/report_test.go
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
package report

import (
"debricked/pkg/client"
"fmt"
"testing"
)

func TestNewReportCmd(t *testing.T) {
cmd := NewReportCmd(client.NewDebClient(nil))
commands := cmd.Commands()
nbrOfCommands := 1
if len(commands) != nbrOfCommands {
t.Error(fmt.Sprintf("failed to assert that there were %d sub commands connected", nbrOfCommands))
}
}
2 changes: 1 addition & 1 deletion pkg/cmd/scan/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func (uploadBatch *uploadBatch) wait() (*scanStatus, error) {
var resultStatus *scanStatus
uri := fmt.Sprintf("/api/1.0/open/ci/upload/status?ciUploadId=%s", strconv.Itoa(uploadBatch.ciUploadId))
for !bar.IsFinished() {
res, err := debClient.Get(uri)
res, err := debClient.Get(uri, "application/json")
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/scan/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func scan(directoryPath string, gitMetaObject *git.MetaObject, ignoredDirectorie

// getSupportedFormats returns all supported dependency file formats
func getSupportedFormats() ([]*file.CompiledFormat, error) {
res, err := debClient.Get("/api/1.0/open/files/supported-formats")
res, err := debClient.Get("/api/1.0/open/files/supported-formats", "application/json")
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit e53c265

Please sign in to comment.