From 6758d154aa8763156a4ad3110c4b3d64cceaa7d5 Mon Sep 17 00:00:00 2001 From: Nejc Habjan Date: Sat, 22 Oct 2022 23:07:49 +0200 Subject: [PATCH] feat: add kas parser --- go.mod | 1 + go.sum | 2 + pkg/git/kas/parse.go | 78 +++++++++++++++++++++ pkg/git/kas/parse_test.go | 52 ++++++++++++++ pkg/git/kas/parse_testcase.go | 50 +++++++++++++ pkg/git/kas/testdata/kas-git-url.yml | 12 ++++ pkg/git/kas/testdata/kas-multiple-repos.yml | 16 +++++ pkg/git/kas/testdata/kas-no-refspec.yml | 11 +++ pkg/git/kas/testdata/kas-ssh-url.yml | 12 ++++ pkg/git/kas/testdata/kas.yml | 12 ++++ 10 files changed, 246 insertions(+) create mode 100644 pkg/git/kas/parse.go create mode 100644 pkg/git/kas/parse_test.go create mode 100644 pkg/git/kas/parse_testcase.go create mode 100644 pkg/git/kas/testdata/kas-git-url.yml create mode 100644 pkg/git/kas/testdata/kas-multiple-repos.yml create mode 100644 pkg/git/kas/testdata/kas-no-refspec.yml create mode 100644 pkg/git/kas/testdata/kas-ssh-url.yml create mode 100644 pkg/git/kas/testdata/kas.yml diff --git a/go.mod b/go.mod index 39cd07d9..12d14f14 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.1 // indirect github.com/liamg/jfather v0.0.7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/whilp/git-urls v1.0.0 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect golang.org/x/text v0.3.3 // indirect diff --git a/go.sum b/go.sum index 523c0419..e8416d86 100644 --- a/go.sum +++ b/go.sum @@ -36,6 +36,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/whilp/git-urls v1.0.0 h1:95f6UMWN5FKW71ECsXRUd3FVYiXdrE7aX4NZKcPmIjU= +github.com/whilp/git-urls v1.0.0/go.mod h1:J16SAmobsqc3Qcy98brfl5f5+e0clUvg1krgwk/qCfE= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= diff --git a/pkg/git/kas/parse.go b/pkg/git/kas/parse.go new file mode 100644 index 00000000..04075535 --- /dev/null +++ b/pkg/git/kas/parse.go @@ -0,0 +1,78 @@ +package kas + +import ( + "fmt" + "strings" + + "golang.org/x/xerrors" + "gopkg.in/yaml.v3" + + dio "github.com/aquasecurity/go-dep-parser/pkg/io" + giturls "github.com/whilp/git-urls" + + "github.com/aquasecurity/go-dep-parser/pkg/types" + "github.com/aquasecurity/go-dep-parser/pkg/utils" +) + +type Repo struct { + Url string `yaml:"url,omitempty"` + RefSpec string `yaml:"refspec,omitempty"` +} + +type KasFile struct { + Repos map[string]Repo `yaml:"repos,omitempty"` +} + +type Parser struct{} + +func NewParser() types.Parser { + return &Parser{} +} + +func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, error) { + var kasFile KasFile + decoder := yaml.NewDecoder(r) + err := decoder.Decode(&kasFile) + if err != nil { + return nil, nil, xerrors.Errorf("decode error: %w", err) + } + + libs, deps := p.parse(&kasFile) + + return libs, deps, nil +} + +func (p *Parser) parse(kasFile *KasFile) ([]types.Library, []types.Dependency) { + var libs []types.Library + + for _, repo := range kasFile.Repos { + name := getRepoNamefromUri(repo.Url) + if name == "" || repo.Url == "" { + continue + } + + version := repo.RefSpec + if version == "" { + version = "latest" + } + + libs = append(libs, types.Library{ + ID: utils.PackageID(name, version), + Name: name, + Version: version, + }) + } + + return libs, nil +} + +func getRepoNamefromUri(rawUri string) string { + uri, err := giturls.Parse(rawUri) + if err != nil { + return "" + } + + name := strings.TrimSuffix(uri.Path, ".git") + name = strings.TrimLeft(name, "/") + return fmt.Sprintf("%s/%s", uri.Host, name) +} diff --git a/pkg/git/kas/parse_test.go b/pkg/git/kas/parse_test.go new file mode 100644 index 00000000..4a6f1462 --- /dev/null +++ b/pkg/git/kas/parse_test.go @@ -0,0 +1,52 @@ +package kas + +import ( + "os" + "path" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/aquasecurity/go-dep-parser/pkg/types" +) + +func TestParse(t *testing.T) { + vectors := []struct { + file string + want []types.Library + }{ + { + file: "testdata/kas.yml", + want: kasRepo, + }, + { + file: "testdata/kas-no-refspec.yml", + want: kasRepoLatest, + }, + { + file: "testdata/kas-git-url.yml", + want: kasRepoGitUrl, + }, + { + file: "testdata/kas-git-url.yml", + want: kasRepoSshUrl, + }, + { + file: "testdata/kas-multiple-repos.yml", + want: kasRepos, + }, + } + + for _, v := range vectors { + t.Run(path.Base(v.file), func(t *testing.T) { + f, err := os.Open(v.file) + require.NoError(t, err) + + got, _, err := NewParser().Parse(f) + require.NoError(t, err) + + assert.Equal(t, v.want, got) + }) + } +} diff --git a/pkg/git/kas/parse_testcase.go b/pkg/git/kas/parse_testcase.go new file mode 100644 index 00000000..ad746739 --- /dev/null +++ b/pkg/git/kas/parse_testcase.go @@ -0,0 +1,50 @@ +package kas + +import "github.com/aquasecurity/go-dep-parser/pkg/types" + +var ( + kasRepo = []types.Library{ + { + ID: "github.com/org/kas@1.0.0", + Name: "github.com/org/kas", + Version: "1.0.0", + }, + } + + kasRepoLatest = []types.Library{ + { + ID: "github.com/org/kas@latest", + Name: "github.com/org/kas", + Version: "latest", + }, + } + + kasRepoGitUrl = []types.Library{ + { + ID: "github.com/org/kas@1.0.0", + Name: "github.com/org/kas", + Version: "1.0.0", + }, + } + + kasRepoSshUrl = []types.Library{ + { + ID: "github.com/org/kas@1.0.0", + Name: "github.com/org/kas", + Version: "1.0.0", + }, + } + + kasRepos = []types.Library{ + { + ID: "github.com/org/kas@1.0.0", + Name: "github.com/org/kas", + Version: "1.0.0", + }, + { + ID: "github.com/user/repo@2.0.0", + Name: "github.com/user/repo", + Version: "2.0.0", + }, + } +) diff --git a/pkg/git/kas/testdata/kas-git-url.yml b/pkg/git/kas/testdata/kas-git-url.yml new file mode 100644 index 00000000..fb060d0c --- /dev/null +++ b/pkg/git/kas/testdata/kas-git-url.yml @@ -0,0 +1,12 @@ +header: + version: 11 + includes: + - repo: externalrepo + file: tests/test_layers/test.yml + +repos: + this: + + externalrepo: + url: git@github.com:org/kas.git + refspec: 1.0.0 diff --git a/pkg/git/kas/testdata/kas-multiple-repos.yml b/pkg/git/kas/testdata/kas-multiple-repos.yml new file mode 100644 index 00000000..82cd12d4 --- /dev/null +++ b/pkg/git/kas/testdata/kas-multiple-repos.yml @@ -0,0 +1,16 @@ +header: + version: 11 + includes: + - repo: externalrepo + file: tests/test_layers/test.yml + +repos: + this: + + externalrepo: + url: https://github.com/org/kas.git + refspec: 1.0.0 + + userrepo: + url: https://github.com/user/repo.git + refspec: 2.0.0 diff --git a/pkg/git/kas/testdata/kas-no-refspec.yml b/pkg/git/kas/testdata/kas-no-refspec.yml new file mode 100644 index 00000000..04229108 --- /dev/null +++ b/pkg/git/kas/testdata/kas-no-refspec.yml @@ -0,0 +1,11 @@ +header: + version: 11 + includes: + - repo: externalrepo + file: tests/test_layers/test.yml + +repos: + this: + + externalrepo: + url: https://github.com/org/kas.git diff --git a/pkg/git/kas/testdata/kas-ssh-url.yml b/pkg/git/kas/testdata/kas-ssh-url.yml new file mode 100644 index 00000000..27d46647 --- /dev/null +++ b/pkg/git/kas/testdata/kas-ssh-url.yml @@ -0,0 +1,12 @@ +header: + version: 11 + includes: + - repo: externalrepo + file: tests/test_layers/test.yml + +repos: + this: + + externalrepo: + url: ssh://git@github.com/org/kas.git + refspec: 1.0.0 diff --git a/pkg/git/kas/testdata/kas.yml b/pkg/git/kas/testdata/kas.yml new file mode 100644 index 00000000..ba161a7f --- /dev/null +++ b/pkg/git/kas/testdata/kas.yml @@ -0,0 +1,12 @@ +header: + version: 11 + includes: + - repo: externalrepo + file: tests/test_layers/test.yml + +repos: + this: + + externalrepo: + url: https://github.com/org/kas.git + refspec: 1.0.0