Skip to content

Commit

Permalink
feat: add SBOM in sync-request metadata (#43)
Browse files Browse the repository at this point in the history
Signed-off-by: felipecruz91 <[email protected]>
  • Loading branch information
felipecruz91 authored Jan 29, 2024
1 parent c03370f commit faa37b7
Show file tree
Hide file tree
Showing 9 changed files with 430 additions and 9 deletions.
13 changes: 10 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,22 @@ go 1.19
require (
cloud.google.com/go/logging v1.8.1
cloud.google.com/go/storage v1.31.0
github.com/google/go-containerregistry v0.18.0
github.com/google/uuid v1.3.1
github.com/hasura/go-graphql-client v0.9.3
github.com/mitchellh/hashstructure/v2 v2.0.1
github.com/sirupsen/logrus v1.9.0
github.com/stretchr/testify v1.8.1
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.4
golang.org/x/oauth2 v0.13.0
google.golang.org/api v0.147.0
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3
)

require (
github.com/kr/text v0.2.0 // indirect
github.com/package-url/packageurl-go v0.1.1 // indirect
)

require (
cloud.google.com/go v0.110.8 // indirect
cloud.google.com/go/compute v1.23.0 // indirect
Expand All @@ -28,7 +34,8 @@ require (
github.com/google/s2a-go v0.1.7 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.1 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/klauspost/compress v1.10.3 // indirect
github.com/klauspost/compress v1.16.5 // indirect
github.com/openvex/go-vex v0.2.5
github.com/pmezard/go-difflib v1.0.0 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
Expand Down
23 changes: 18 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -74,6 +75,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.18.0 h1:ShE7erKNPqRh5ue6Z9DUOlk04WsnFWPO6YGr3OxnfoQ=
github.com/google/go-containerregistry v0.18.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
Expand All @@ -96,8 +99,12 @@ github.com/hasura/go-graphql-client v0.9.3 h1:Xi3fqa2t9q4nJ2jM2AU8nB6qeAoMpbcYDi
github.com/hasura/go-graphql-client v0.9.3/go.mod h1:AarJlxO1I59MPqU/TC7gQP0BMFgPEqUTt5LYPvykasw=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
Expand All @@ -109,11 +116,16 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/openvex/go-vex v0.2.5 h1:41utdp2rHgAGCsG+UbjmfMG5CWQxs15nGqir1eRgSrQ=
github.com/openvex/go-vex v0.2.5/go.mod h1:j+oadBxSUELkrKh4NfNb+BPo77U3q7gdKME88IO/0Wo=
github.com/package-url/packageurl-go v0.1.1 h1:KTRE0bK3sKbFKAk3yy63DpeskU7Cvs/x/Da5l+RtzyU=
github.com/package-url/packageurl-go v0.1.1/go.mod h1:uQd4a7Rh3ZsVg5j0lNyAfyxIeGde9yrlhjF78GzeW0c=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
Expand All @@ -122,8 +134,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
Expand Down Expand Up @@ -222,8 +235,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
Expand Down
65 changes: 65 additions & 0 deletions policy/policy_handler/legacy/builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package legacy

import (
"github.com/atomist-skills/go-skill/policy/types"
"olympos.io/encoding/edn"
)

func BuildLocalEvalMocks(sb *types.SBOM) map[edn.Keyword]edn.RawMessage {
m := map[edn.Keyword]edn.RawMessage{}
if sb == nil {
return m
}

m[ImagePackagesByDigestQueryName], _ = edn.Marshal(MockImagePackagesByDigestForLocalEval(sb))

if sb.Source.Image != nil && sb.Source.Image.Config != nil {
m[GetUserQueryName], _ = edn.Marshal(MockGetUserForLocalEval(sb.Source.Image.Config.Config.User))
}

return m
}

func MockImagePackagesByDigestForLocalEval(sb *types.SBOM) ImagePackagesByDigestResponse {
vulns := map[string][]Vulnerability{}
for _, tuple := range sb.Vulnerabilities {
vulnsForPurl := []Vulnerability{}
for _, v := range tuple.Vulnerabilities {
vulnsForPurl = append(vulnsForPurl, Vulnerability{
Cvss: Cvss{
Severity: &v.Cvss.Severity,
Score: &v.Cvss.Score,
},
FixedBy: &v.FixedBy,
Source: v.Source,
SourceID: v.SourceId,
URL: &v.Url,
VulnerableRange: v.VulnerableRange,
})
}
vulns[tuple.Purl] = vulnsForPurl
}

pkgs := []Packages{}
for _, a := range sb.Artifacts {
pkgs = append(pkgs, Packages{
Package: PackageWithLicenses{
Licenses: a.Licenses,
Name: a.Name,
Namespace: &a.Namespace,
Version: a.Version,
Purl: a.Purl,
Type: a.Type,
Vulnerabilities: vulns[a.Purl],
},
})
}

return ImagePackagesByDigestResponse{
ImagePackagesByDigest: &ImagePackagesByDigest{
ImagePackages: ImagePackages{
Packages: pkgs,
},
},
}
}
99 changes: 99 additions & 0 deletions policy/policy_handler/legacy/builder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package legacy

import (
"reflect"
"testing"

"github.com/atomist-skills/go-skill/policy/types"
v1 "github.com/google/go-containerregistry/pkg/v1"
"olympos.io/encoding/edn"
)

func Test_BuildLocalEvalMocks(t *testing.T) {
type args struct {
sb *types.SBOM
}
tests := []struct {
name string
args args
want map[edn.Keyword]edn.RawMessage
}{
{
name: "Without SBOM",
args: args{
sb: nil,
},
want: map[edn.Keyword]edn.RawMessage{},
},
{
name: "With SBOM",
args: args{
sb: &types.SBOM{
Source: types.Source{
Image: &types.ImageSource{
Config: &v1.ConfigFile{
Config: v1.Config{
User: "root",
},
},
},
},
Artifacts: []types.Package{
{
Name: "pkg1",
},
},
},
},
want: map[edn.Keyword]edn.RawMessage{
"image-packages-by-digest": []byte(`{:imagePackagesByDigest{:imagePackages{:packages[{:package{:licenses nil :name"pkg1":namespace"":version"":purl"":type"":vulnerabilities nil}}]}}}`),
"get-user": []byte(`{:docker.image/user"root"}`),
},
},
{
name: "SBOM without image source",
args: args{
sb: &types.SBOM{
Source: types.Source{
Image: nil,
},
Artifacts: []types.Package{
{
Name: "pkg1",
},
},
},
},
want: map[edn.Keyword]edn.RawMessage{
"image-packages-by-digest": []byte(`{:imagePackagesByDigest{:imagePackages{:packages[{:package{:licenses nil :name"pkg1":namespace"":version"":purl"":type"":vulnerabilities nil}}]}}}`),
},
},
{
name: "SBOM without image config file",
args: args{
sb: &types.SBOM{
Source: types.Source{
Image: &types.ImageSource{
Config: nil,
},
},
Artifacts: []types.Package{
{
Name: "pkg1",
},
},
},
},
want: map[edn.Keyword]edn.RawMessage{
"image-packages-by-digest": []byte(`{:imagePackagesByDigest{:imagePackages{:packages[{:package{:licenses nil :name"pkg1":namespace"":version"":purl"":type"":vulnerabilities nil}}]}}}`),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := BuildLocalEvalMocks(tt.args.sb); !reflect.DeepEqual(got, tt.want) {
t.Errorf("BuildLocalEvalMocks() = %v, want %v", got, tt.want)
}
})
}
}
15 changes: 15 additions & 0 deletions policy/policy_handler/legacy/get_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package legacy

const (
GetUserQueryName = "get-user"
)

type DockerImageUser struct {
ImageUser string `edn:"docker.image/user,omitempty"`
}

func MockGetUserForLocalEval(user string) DockerImageUser {
return DockerImageUser{
ImageUser: user,
}
}
7 changes: 7 additions & 0 deletions policy/policy_handler/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package policy_handler
import (
"context"
"fmt"

"github.com/atomist-skills/go-skill"
"github.com/atomist-skills/go-skill/policy/data"
"github.com/atomist-skills/go-skill/policy/goals"
"github.com/atomist-skills/go-skill/policy/policy_handler/legacy"
"github.com/atomist-skills/go-skill/policy/types"
"olympos.io/encoding/edn"
)

Expand All @@ -16,6 +18,7 @@ type SyncRequestMetadata struct {
QueryResults map[edn.Keyword]edn.RawMessage `edn:"fixedQueryResults"`
Packages []legacy.Package `edn:"packages"` // todo remove when no longer used
User string `edn:"imgConfigUser"` // The user from the image config blob // todo remove when no longer used
SBOM *types.SBOM `edn:"sbom"`
}

func WithLocal() Opt {
Expand Down Expand Up @@ -56,6 +59,10 @@ func buildLocalDataSources(ctx context.Context, req skill.RequestContext, _ goal
return nil, fmt.Errorf("failed to unmarshal SyncRequest metadata: %w", err)
}

if srMeta.SBOM != nil {
srMeta.QueryResults = legacy.BuildLocalEvalMocks(srMeta.SBOM)
}

fixedQueryResults := map[string][]byte{}
for k, v := range srMeta.QueryResults {
fixedQueryResults[string(k)] = v
Expand Down
3 changes: 2 additions & 1 deletion policy/policy_handler/local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package policy_handler

import (
"context"
"testing"

"github.com/atomist-skills/go-skill"
"github.com/atomist-skills/go-skill/policy/goals"
"github.com/stretchr/testify/assert"
"olympos.io/encoding/edn"
"testing"
)

type TestQueryResultFields struct {
Expand Down
Loading

0 comments on commit faa37b7

Please sign in to comment.