Skip to content

Commit

Permalink
Feat/pr comment (#111)
Browse files Browse the repository at this point in the history
* feat(pr-comments): github support

Adding PR comments for every secret or misconf findings

* feat(comments): gitlab

* lint

Co-authored-by: oranmoshai <oran.moshai@aquasec.com>
  • Loading branch information
oranmoshai and oranmoshai authored May 31, 2022
1 parent eae3cf7 commit 698aeb3
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 30 deletions.
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ go 1.18
require (
github.com/aquasecurity/fanal v0.0.0-20220503163617-7b81bb08565f
github.com/aquasecurity/go-dep-parser v0.0.0-20220503151658-d316f5cc2cff
github.com/aquasecurity/go-git-pr-commenter v0.0.0-20220530100252-61bd9b3af2df
github.com/aquasecurity/trivy v0.27.1-0.20220426130527-b6baa65ff20b
github.com/aquasecurity/trivy-db v0.0.0-20220327074450-74195d9604b2
github.com/mitchellh/mapstructure v1.5.0
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.7.1
github.com/thoas/go-funk v0.9.2
github.com/twitchtv/twirp v8.1.2+incompatible
github.com/urfave/cli/v2 v2.4.0
github.com/urfave/cli/v2 v2.5.1
go.uber.org/zap v1.21.0
golang.org/x/text v0.3.7
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
Expand Down Expand Up @@ -87,6 +88,8 @@ require (
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-containerregistry v0.7.1-0.20211214010025-a65b7844a475 // indirect
github.com/google/go-github/v44 v44.1.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/google/wire v0.5.0 // indirect
github.com/googleapis/gax-go/v2 v2.1.1 // indirect
Expand Down Expand Up @@ -160,7 +163,7 @@ require (
golang.org/x/exp v0.0.0-20220407100705-7b9b53b0aca4 // indirect
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57 // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
golang.org/x/tools v0.1.8 // indirect
Expand Down
17 changes: 12 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ github.com/aquasecurity/go-dep-parser v0.0.0-20220503151658-d316f5cc2cff h1:YNlz
github.com/aquasecurity/go-dep-parser v0.0.0-20220503151658-d316f5cc2cff/go.mod h1:7EOQWQmyavVPY3fScbbPdd3dB/b0Q4ZbJ/NZCvNKrLs=
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM=
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce/go.mod h1:HXgVzOPvXhVGLJs4ZKO817idqr/xhwsTcj17CLYY74s=
github.com/aquasecurity/go-git-pr-commenter v0.0.0-20220530100252-61bd9b3af2df h1:+XkzXb+3fykN/cG6/agPyaUrNgM+6AHeQy8ZFYwfbWY=
github.com/aquasecurity/go-git-pr-commenter v0.0.0-20220530100252-61bd9b3af2df/go.mod h1:qqqStAf73A6em7ZqAIKXFSgLp3dm5EQaPFfuLU5dU7E=
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 h1:eveqE9ivrt30CJ7dOajOfBavhZ4zPqHcZe/4tKp0alc=
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798/go.mod h1:hxbJZtKlO4P8sZ9nztizR6XLoE33O+BkPmuYQ4ACyz0=
github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 h1:vmXNl+HDfqqXgr0uY1UgK1GAhps8nbAAtqHNBcgyf+4=
Expand Down Expand Up @@ -822,16 +824,20 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-containerregistry v0.0.0-20191010200024-a3d713f9b7f8/go.mod h1:KyKXa9ciM8+lgMXwOVsXi7UxGrsf9mM61Mzs+xKUrKE=
github.com/google/go-containerregistry v0.1.2/go.mod h1:GPivBPgdAyd2SU+vf6EpsgOtWDuPqjW0hJZt4rNdTZ4=
github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0=
github.com/google/go-containerregistry v0.7.1-0.20211214010025-a65b7844a475 h1:da8EHPcyjqM4dHLhPqtY48YUj9ATT1ugRyi4g+MdITM=
github.com/google/go-containerregistry v0.7.1-0.20211214010025-a65b7844a475/go.mod h1:IwJblnDNiCs8sxubbfPNniYsUqr8m+nt7YbPzecsGuE=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
github.com/google/go-github/v44 v44.1.0 h1:shWPaufgdhr+Ad4eo/pZv9ORTxFpsxPEPEuuXAKIQGA=
github.com/google/go-github/v44 v44.1.0/go.mod h1:iWn00mWcP6PRWHhXm0zuFJ8wbEjE5AGO5D5HXYM4zgw=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE=
github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
Expand Down Expand Up @@ -1535,8 +1541,8 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/urfave/cli/v2 v2.4.0 h1:m2pxjjDFgDxSPtO8WSdbndj17Wu2y8vOT86wE/tjr+I=
github.com/urfave/cli/v2 v2.4.0/go.mod h1:NX9W0zmTvedE5oDoOMs2RTC8RvdK98NTYZE5LbaEYPg=
github.com/urfave/cli/v2 v2.5.1 h1:YKwdkyA0xTBzOaP2G0DVxBnCheHGP+Y9VbKAs4K1Ess=
github.com/urfave/cli/v2 v2.5.1/go.mod h1:oDzoM7pVwz6wHn5ogWgFUU1s4VJayeQS+aEZDqXIEJs=
github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
Expand Down Expand Up @@ -1859,8 +1865,9 @@ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -2607,4 +2614,4 @@ sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
sourcegraph.com/sqs/pbtypes v1.0.0/go.mod h1:3AciMUv4qUuRHRHhOG4TZOB+72GdPVz5k+c648qsFS4=
sourcegraph.com/sqs/pbtypes v1.0.0/go.mod h1:3AciMUv4qUuRHRHhOG4TZOB+72GdPVz5k+c648qsFS4=
125 changes: 125 additions & 0 deletions pkg/buildClient/comments.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package buildClient

import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"

"github.com/aquasecurity/go-git-pr-commenter/pkg/commenter"
"github.com/aquasecurity/go-git-pr-commenter/pkg/commenter/github"
"github.com/aquasecurity/go-git-pr-commenter/pkg/commenter/gitlab"
"github.com/aquasecurity/trivy-plugin-aqua/pkg/metadata"
"github.com/aquasecurity/trivy-plugin-aqua/pkg/proto/buildsecurity"
)

// prComments send results PR comments
func prComments(buildSystem string, result []*buildsecurity.Result) error {
var c = commenter.Repository(nil)
switch buildSystem {
case metadata.Github:
owner, repo, err := getGitHubRepositoryDetails()
if err != nil {
return err
}
prNumber, err := extractGitHubActionPrNumber()
if err != nil {
return err
}
r, err := github.NewGithub(os.Getenv("GITHUB_TOKEN"),
owner,
repo,
prNumber)
if err != nil {
return err
}
c = commenter.Repository(r)
case metadata.Gitlab:
r, err := gitlab.NewGitlab(os.Getenv("GITLAB_TOKEN"))
if err != nil {
return err
}
c = commenter.Repository(r)
default:
return nil
}

for _, r := range result {
switch r.Type {
case buildsecurity.Result_TYPE_TERRAFORM, buildsecurity.Result_TYPE_CLOUDFORMATION,
buildsecurity.Result_TYPE_KUBERNETES, buildsecurity.Result_TYPE_DOCKERFILE,
buildsecurity.Result_TYPE_HCL, buildsecurity.Result_TYPE_YAML:
err := c.WriteMultiLineComment(r.Filename, returnMisconfMsg(r), int(r.StartLine), int(r.EndLine))
if err != nil {
return fmt.Errorf("failed write misconfiguration comment: %w", err)
}

case buildsecurity.Result_TYPE_SECRETS:
err := c.WriteMultiLineComment(r.Filename, returnSecretMsg(r), int(r.StartLine), int(r.EndLine))
if err != nil {
return fmt.Errorf("failed write secret findings comment: %w", err)
}
}
}

return nil
}

func returnSecretMsg(r *buildsecurity.Result) string {
return fmt.Sprintf("### :warning: Aqua found issue"+
"\n<b>CATEGORY:</b> %s "+
"\n<b>DESCRIPTION:</b> %s "+
"\n<b>SEVERITY:</b> %s "+
"\n<b>MATCH:</b> %s",
r.Resource,
r.Title,
r.Severity.String(),
r.Message)
}
func returnMisconfMsg(r *buildsecurity.Result) string {
return fmt.Sprintf("### :warning: Aqua found issue "+
"\n<b>MISCONF ID:</b> %s "+
"\n<b>CHECK:</b> %s "+
"\n<b>SEVERITY:</b> %s "+
"\n<b>MESSAGE:</b> %s",
r.AVDID,
r.Title,
r.Severity.String(),
r.Message)
}

func getGitHubRepositoryDetails() (owner, repo string, err error) {
r := os.Getenv("GITHUB_REPOSITORY")
s := strings.Split(r, "/")
if len(s) != 2 {
return owner, repo,
fmt.Errorf("failed unexpected value for GITHUB_REPOSITORY."+
" Expected <organisation/name>, found %v", r)
}

return s[0], s[1], nil
}

// extractGitHubActionPrNumber take the pull request number from the GitHub action run
func extractGitHubActionPrNumber() (int, error) {
githubEventFile := "/github/workflow/event.json"
file, err := ioutil.ReadFile(githubEventFile)
if err != nil {
return 0, fmt.Errorf("failed gitHub event payload not found in %s", githubEventFile)
}

var data interface{}
err = json.Unmarshal(file, &data)
if err != nil {
return 0, err
}
payload := data.(map[string]interface{})

prNumber, err := strconv.Atoi(fmt.Sprintf("%v", payload["number"]))
if err != nil {
return 0, fmt.Errorf("failed not a valid PR")
}
return prNumber, nil
}
14 changes: 13 additions & 1 deletion pkg/buildClient/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"net/http"

"github.com/aquasecurity/trivy-plugin-aqua/pkg/log"

"github.com/aquasecurity/trivy-plugin-aqua/pkg/scanner"

"github.com/aquasecurity/trivy-plugin-aqua/pkg/metadata"
Expand All @@ -29,6 +31,7 @@ func (bc *TwirpClient) Upload(results []*buildsecurity.Result, tags map[string]s

run, buildID := metadata.GetBuildInfo(buildSystem)

triggeredBy := bc.c.String("triggered-by")
createScanReq := &buildsecurity.CreateScanReq{
RepositoryID: bc.repoId,
Results: results,
Expand All @@ -37,7 +40,7 @@ func (bc *TwirpClient) Upload(results []*buildsecurity.Result, tags map[string]s
Commit: commitId,
System: buildSystem,
Tags: tags,
TriggeredBy: scanner.MatchTriggeredBy(bc.c.String("triggered-by")),
TriggeredBy: scanner.MatchTriggeredBy(triggeredBy),
Run: run,
BuildID: buildID,
}
Expand All @@ -46,5 +49,14 @@ func (bc *TwirpClient) Upload(results []*buildsecurity.Result, tags map[string]s
if err != nil {
return fmt.Errorf("failed sending results with error: %w", err)
}

// Send pull request comments
if triggeredBy == "pr" && len(results) > 0 {
err = prComments(buildSystem, results)
if err != nil {
log.Logger.Info("failed send PR comment logging and continue the scan err: ", err)
}
}

return nil
}
24 changes: 12 additions & 12 deletions pkg/metadata/build_env_vars.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package metadata

const (
bitbucket = "bitbucket"
jenkins = "jenkins"
gitlab = "gitlab"
codebuild = "codebuild"
azure = "azure"
github = "github"
Bitbucket = "bitbucket"
Jenkins = "jenkins"
Gitlab = "gitlab"
Codebuild = "codebuild"
Azure = "azure"
Github = "github"
overrideBuildSystem = "OVERRIDE_BUILDSYSTEM"
)

Expand Down Expand Up @@ -45,10 +45,10 @@ var possibleUserEnvVars = []string{
}

var possibleBuildSystems = map[string]string{
"BITBUCKET_COMMIT": bitbucket,
"GIT_COMMIT": jenkins,
"CI_COMMIT_SHA": gitlab,
"CODEBUILD_GIT_COMMIT": codebuild,
"BUILD_SOURCEBRANCH": azure,
"GITHUB_SHA": github,
"BITBUCKET_COMMIT": Bitbucket,
"GIT_COMMIT": Jenkins,
"CI_COMMIT_SHA": Gitlab,
"CODEBUILD_GIT_COMMIT": Codebuild,
"BUILD_SOURCEBRANCH": Azure,
"GITHUB_SHA": Github,
}
10 changes: 5 additions & 5 deletions pkg/metadata/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,15 +264,15 @@ func lastLogsHead(scanPath string) (s []string, err error) {
// GetBuildInfo the vendor build run number and id
func GetBuildInfo(buildSystem string) (run string, buildID string) {
switch buildSystem {
case github:
case Github:
return os.Getenv("GITHUB_RUN_NUMBER"), os.Getenv("GITHUB_RUN_ID")
case bitbucket:
case Bitbucket:
return os.Getenv("BITBUCKET_BUILD_NUMBER"), os.Getenv("BITBUCKET_PR_ID")
case gitlab:
case Gitlab:
return os.Getenv("CI_JOB_ID"), os.Getenv("CI_MERGE_REQUEST_IID")
case azure:
case Azure:
return os.Getenv("BUILD_BUILDID"), os.Getenv("SYSTEM_PULLREQUEST_PULLREQUESTID")
case jenkins:
case Jenkins:
return os.Getenv("BUILD_ID"), os.Getenv("BUILD_NUMBER")
default:
return "", ""
Expand Down
10 changes: 5 additions & 5 deletions pkg/metadata/pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ import (
func GetBaseRef() (r string) {
buildSystem := GetBuildSystem()
switch buildSystem {
case azure:
case Azure:
return fmt.Sprintf(
"origin/%s",
strings.ReplaceAll(os.Getenv("SYSTEM_PULLREQUEST_TARGETBRANCH"), "refs/heads/", ""))
case bitbucket:
case Bitbucket:
return os.Getenv("BITBUCKET_PR_DESTINATION_COMMIT")
case github:
case Github:
return "FETCH_HEAD"
case gitlab:
case Gitlab:
return os.Getenv("CI_MERGE_REQUEST_DIFF_BASE_SHA")
case jenkins:
case Jenkins:
return fmt.Sprintf("origin/%s", os.Getenv("CHANGE_TARGET"))
default:
return "origin/master"
Expand Down

0 comments on commit 698aeb3

Please sign in to comment.