Skip to content

Commit

Permalink
Start adding Snyk commands
Browse files Browse the repository at this point in the history
This is a big change, moving the top level enrich command to the
ecosystems subcommand, and adding a snyk subcommand. Still some
refactoring to do, but this is a working version.
  • Loading branch information
garethr committed May 6, 2023
1 parent 6313a65 commit e3440db
Show file tree
Hide file tree
Showing 14 changed files with 2,158 additions and 19 deletions.
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@ cover:
specs:
@curl --silent https://packages.ecosyste.ms/docs/api/v1/openapi.yaml -o specs/packages.yaml
@curl --silent https://repos.ecosyste.ms/docs/api/v1/openapi.yaml -o specs/repos.yaml
@curl --silent https://api.snyk.io/rest/openapi/2023-04-28~experimental -o specs/snyk-experimental.json
@curl --silent https://api.snyk.io/rest/openapi/2023-04-28 -o specs/snyk.json

clients: specs
@oapi-codegen -generate types,client -package packages specs/packages.yaml > ecosystems/packages/packages.go
@oapi-codegen -generate types,client -package repos specs/repos.yaml > ecosystems/repos/repos.go
@oapi-codegen -generate types,client -package users -include-tags Users specs/snyk-experimental.json > snyk/users/users.go
@oapi-codegen -generate types,client -package issues -include-tags Issues specs/snyk.json > snyk/issues/issues.go
sed -i '' 's/"purl", runtime.ParamLocationPath, purl/"purl", runtime.ParamLocationQuery, purl/' snyk/issues/issues.go

fmt:
@gofmt -s -w -l .


.PHONY: build test acceptance lint cover specs clients fmt
.PHONY: build test acceptance lint cover specs patch clients fmt
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ $ cat testing/sbom.cyclonedx.json
"purl": "pkg:npm/[email protected]"
}
...
$ cat testing/sbom.cyclonedx.json | parlay enrich - | jq
$ cat testing/sbom.cyclonedx.json | parlay e enrich - | jq
...
{
"bom-ref": "[email protected]",
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.20
require (
github.com/CycloneDX/cyclonedx-go v0.7.1
github.com/deepmap/oapi-codegen v1.12.4
github.com/google/uuid v1.3.0
github.com/jarcoal/httpmock v1.3.0
github.com/package-url/packageurl-go v0.1.0
github.com/remeh/sizedwaitgroup v1.0.0
Expand All @@ -15,7 +16,6 @@ require (
require (
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
Expand Down
17 changes: 7 additions & 10 deletions internal/commands/default.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
package commands

import (
"log"
"os"

"github.com/snyk/parlay/internal/commands/ecosystems"
"github.com/snyk/parlay/internal/commands/snyk"

"github.com/spf13/cobra"
)

func NewDefaultCommand() *cobra.Command {
cmd := cobra.Command{
Use: "parlay",
Short: "",
Long: ``,
SilenceUsage: true,
Use: "parlay",
Short: "",
Long: ``,
SilenceUsage: true,
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
_ = cmd.Help()
},
}

logger := log.New(os.Stdout, "", log.LstdFlags)

cmd.AddCommand(NewEnrichCommand(logger))
cmd.AddCommand(ecosystems.NewEcosystemsRootCommand())
cmd.AddCommand(snyk.NewSnykRootCommand())

return &cmd
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package commands
package ecosystems

import (
"bufio"
Expand Down
16 changes: 12 additions & 4 deletions internal/commands/ecosystems/root.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
package ecosystems

import (
"log"
"os"

"github.com/spf13/cobra"
)

func NewEcosystemsRootCommand() *cobra.Command {
cmd := cobra.Command{
Use: "ecosystems",
Short: "",
Long: ``,
SilenceUsage: true,
Use: "ecosystems",
Short: "",
Long: ``,
Aliases: []string{"e"},
DisableFlagsInUseLine: true,
SilenceUsage: true,
Run: func(cmd *cobra.Command, args []string) {
_ = cmd.Help()
},
}
logger := log.New(os.Stdout, "", log.LstdFlags)

cmd.AddCommand(NewPackageCommand())
cmd.AddCommand(NewRepoCommand())
cmd.AddCommand(NewEnrichCommand(logger))

return &cmd
}
31 changes: 31 additions & 0 deletions internal/commands/snyk/packages.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package snyk

import (
"fmt"
"log"

"github.com/snyk/parlay/lib"

"github.com/package-url/packageurl-go"
"github.com/spf13/cobra"
)

func NewPackageCommand() *cobra.Command {
cmd := cobra.Command{
Use: "package <purl> ",
Short: "Return package vulnerabilities from Snyk",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
purl, err := packageurl.FromString(args[0])
if err != nil {
log.Fatal(err)
}
resp, err := lib.GetPackageVulnerabilities(purl)
if err != nil {
log.Fatal(err)
}
fmt.Print(string(resp.Body))
},
}
return &cmd
}
20 changes: 20 additions & 0 deletions internal/commands/snyk/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package snyk

import (
"github.com/spf13/cobra"
)

func NewSnykRootCommand() *cobra.Command {
cmd := cobra.Command{
Use: "snyk",
Short: "",
Long: ``,
SilenceUsage: true,
Run: func(cmd *cobra.Command, args []string) {
_ = cmd.Help()
},
}
cmd.AddCommand(NewPackageCommand())

return &cmd
}
36 changes: 36 additions & 0 deletions lib/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,51 @@ package lib

import (
"context"
"errors"
"fmt"
"net/url"
"os"

"github.com/snyk/parlay/ecosystems/packages"
"github.com/snyk/parlay/snyk/issues"

"github.com/deepmap/oapi-codegen/pkg/securityprovider"
"github.com/package-url/packageurl-go"
)

const server = "https://packages.ecosyste.ms/api/v1"
const snykServer = "https://api.snyk.io/rest"
const version = "2023-04-28"

func GetPackageVulnerabilities(purl packageurl.PackageURL) (*issues.FetchIssuesPerPurlResponse, error) {
token := os.Getenv("SNYK_TOKEN")
if token == "" {
return nil, errors.New("Must provide a SNYK_TOKEN environment variable")
}

auth, err := securityprovider.NewSecurityProviderApiKey("header", "Authorization", fmt.Sprintf("token %s", token))
if err != nil {
return nil, err
}

org, err := getSnykOrg(auth)
if err != nil {
return nil, err
}

client, err := issues.NewClientWithResponses(snykServer, issues.WithRequestEditorFn(auth.Intercept))
if err != nil {
return nil, err
}

params := issues.FetchIssuesPerPurlParams{Version: version}
resp, err := client.FetchIssuesPerPurlWithResponse(context.Background(), *org, purl.ToString(), &params)
if err != nil {
return nil, err
}

return resp, nil
}

func GetPackageData(purl packageurl.PackageURL) (*packages.GetRegistryPackageResponse, error) {
client, err := packages.NewClientWithResponses(server)
Expand Down
53 changes: 53 additions & 0 deletions lib/self.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package lib

import (
"context"
"encoding/json"

"github.com/snyk/parlay/snyk/users"

"github.com/deepmap/oapi-codegen/pkg/securityprovider"
"github.com/google/uuid"
)

const experimentalVersion = "2023-04-28~experimental"

type selfDocument struct {
Data struct {
Attributes struct {
AvatarURL string `json:"avatar_url,omitempty"`
DefaultOrgContext string `json:"default_org_context,omitempty"`
Name string `json:"name,omitempty"`
Username string `json:"username,omitempty"`
} `json:"attributes,omitempty"`
ID string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
}
Jsonapi interface{} `json:"jsonapi,omitempty"`
Links interface{} `json:"links,omitempty"`
}

func getSnykOrg(auth *securityprovider.SecurityProviderApiKey) (*uuid.UUID, error) {
experimental, err := users.NewClientWithResponses(snykServer, users.WithRequestEditorFn(auth.Intercept))
if err != nil {
return nil, err
}

userParams := users.GetSelfParams{Version: experimentalVersion}
self, err := experimental.GetSelfWithResponse(context.Background(), &userParams)
if err != nil {
return nil, err
}

var userInfo selfDocument
if err = json.Unmarshal(self.Body, &userInfo); err != nil {
return nil, err
}

orgId := userInfo.Data.Attributes.DefaultOrgContext
org, err := uuid.Parse(orgId)
if err != nil {
return nil, err
}
return &org, nil
}
Loading

0 comments on commit e3440db

Please sign in to comment.