rough draft for plugin system

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman 2020-09-02 23:34:00 -04:00
parent 63ee5ba098
commit 3e27b6e93f
No known key found for this signature in database
GPG Key ID: 86E2870463D5E890
27 changed files with 1491 additions and 15 deletions

View File

@ -31,7 +31,7 @@ linters:
- misspell
- nakedret
- nolintlint
- prealloc
# - prealloc
- rowserrcheck
- scopelint
- staticcheck

View File

@ -169,6 +169,9 @@ check-pipeline: ## Run local CircleCI pipeline locally (sanity check)
circleci local execute -c .tmp/circleci.yml --job "Unit & Integration Tests (go-latest)"
@printf '$(SUCCESS)Pipeline checks pass!$(RESET)\n'
proto:
protoc -I syft/plugin/proto/ syft/plugin/proto/cataloger.proto --go_out=plugins=grpc:syft/plugin/proto/
.PHONY: build
build: $(SNAPSHOTDIR) ## Build release snapshot binaries and packages

View File

@ -3,6 +3,10 @@ package cmd
import (
"fmt"
"os"
"path"
"github.com/adrg/xdg"
"github.com/anchore/syft/internal"
"github.com/spf13/cobra"
@ -78,6 +82,18 @@ func setGlobalCliOptions() {
}
rootCmd.Flags().CountVarP(&cliOpts.Verbosity, "verbose", "v", "increase verbosity (-v = info, -vv = debug)")
// plugins
defaultPluginDir := path.Join(xdg.ConfigHome, internal.ApplicationName, "plugins")
flag = "plugins.dir"
rootCmd.Flags().String(
flag, defaultPluginDir,
"plugin storage directory",
)
if err := viper.BindPFlag(flag, rootCmd.Flags().Lookup(flag)); err != nil {
fmt.Printf("unable to bind flag '%s': %+v", flag, err)
os.Exit(1)
}
}
func initAppConfig() {

3
go.mod
View File

@ -12,11 +12,13 @@ require (
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe // indirect
github.com/dustin/go-humanize v1.0.0
github.com/go-test/deep v1.0.6
github.com/golang/protobuf v1.4.2
github.com/google/go-containerregistry v0.1.1 // indirect
github.com/google/uuid v1.1.1
github.com/gookit/color v1.2.7
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 // indirect
github.com/hashicorp/go-multierror v1.1.0
github.com/hashicorp/go-plugin v1.3.0
github.com/hashicorp/go-version v1.2.0
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/mapstructure v1.3.1
@ -39,6 +41,7 @@ require (
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 // indirect
golang.org/x/sys v0.0.0-20200610111108-226ff32320da // indirect
google.golang.org/genproto v0.0.0-20200615140333-fd031eab31e7 // indirect
google.golang.org/grpc v1.31.1
gopkg.in/ini.v1 v1.57.0 // indirect
gopkg.in/yaml.v2 v2.3.0
)

16
go.sum
View File

@ -474,12 +474,16 @@ github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/U
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-plugin v1.3.0 h1:4d/wJojzvHV1I4i/rrjVaeuyxWrLzDE1mDCyDy8fXS8=
github.com/hashicorp/go-plugin v1.3.0/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0=
github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-retryablehttp v0.6.6 h1:HJunrbHTDDbBb/ay4kxa1n+dLmttUlnP3V9oNE4hmsM=
github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
@ -500,6 +504,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@ -510,6 +516,7 @@ github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a h1:GmsqmapfzSJkm28dhRoHz2tLRbJmqhU86IPgBtN3mmk=
github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s=
github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
@ -611,6 +618,8 @@ github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
@ -639,6 +648,8 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
@ -923,6 +934,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -1148,6 +1160,7 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -1181,6 +1194,7 @@ google.golang.org/genproto v0.0.0-20200604104852-0b0486081ffb h1:ek2py5bOqzR7MR/
google.golang.org/genproto v0.0.0-20200604104852-0b0486081ffb/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200615140333-fd031eab31e7 h1:1N7l1PuXZwEK7OhHdmKQROOM75PnUjABGwvVRbLBgFk=
google.golang.org/genproto v0.0.0-20200615140333-fd031eab31e7/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@ -1195,6 +1209,8 @@ google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=

View File

@ -28,7 +28,13 @@ type Application struct {
Quiet bool `mapstructure:"quiet"`
Log Logging `mapstructure:"log"`
CliOptions CliOnlyOptions
CheckForAppUpdate bool `mapstructure:"check-for-app-update"`
CheckForAppUpdate bool `mapstructure:"check-for-app-update"`
Plugins Plugins `mapstructure:"plugins"`
}
type Plugins struct {
Enabled bool `mapstructure:"enabled"`
Directory string `mapstructure:"dir"`
}
type Logging struct {

View File

@ -4,11 +4,12 @@ Package apkdb provides a concrete Cataloger implementation for Alpine DB files.
package apkdb
import (
"io"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/cataloger/common"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"io"
)
// Cataloger catalogs pkg.ApkPkg Package Types defined in Alpine DB files.

View File

@ -4,11 +4,12 @@ Package bundler provides a concrete Cataloger implementation for Ruby Gemfile.lo
package bundler
import (
"io"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/cataloger/common"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"io"
)
// Cataloger catalogs pkg.GemPkg Package Types defined in Bundler Gemfile.lock files.

View File

@ -6,6 +6,8 @@ catalogers defined in child packages as well as the interface definition to impl
package cataloger
import (
"io"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/cataloger/apkdb"
"github.com/anchore/syft/syft/cataloger/bundler"
@ -17,7 +19,6 @@ import (
"github.com/anchore/syft/syft/cataloger/rpmdb"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"io"
)
// Cataloger describes behavior for an object to participate in parsing container image or file system

View File

@ -4,11 +4,12 @@ Package common provides generic utilities used by multiple catalogers.
package common
import (
"io"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"io"
)
// GenericCataloger implements the Catalog interface and is responsible for dispatching the proper parser function for

View File

@ -4,11 +4,12 @@ Package dpkg provides a concrete Cataloger implementation for Debian package DB
package dpkg
import (
"io"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/cataloger/common"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"io"
)
// Cataloger catalogs pkg.DebPkg Package Types defined in DPKG status files.

View File

@ -4,11 +4,12 @@ Package golang provides a concrete Cataloger implementation for go.mod files.
package golang
import (
"io"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/cataloger/common"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"io"
)
// Cataloger catalogs pkg.GoModulePkg Package Types defined in go.mod files.

View File

@ -4,11 +4,12 @@ Package java provides a concrete Cataloger implementation for Java archives (jar
package java
import (
"io"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/cataloger/common"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"io"
)
// Cataloger catalogs pkg.JavaPkg and pkg.JenkinsPluginPkg Package Types defined in java archive files.

View File

@ -4,11 +4,12 @@ Package javascript provides a concrete Cataloger implementation for JavaScript e
package javascript
import (
"io"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/cataloger/common"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"io"
)
// Cataloger catalogs pkg.YarnPkg and pkg.NpmPkg Package Types defined in package-lock.json and yarn.lock files.

View File

@ -4,11 +4,12 @@ Package python provides a concrete Cataloger implementation for Python ecosystem
package python
import (
"io"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/cataloger/common"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"io"
)
// Cataloger catalogs pkg.WheelPkg, pkg.EggPkg, and pkg.PythonRequirementsPkg Package Types defined in Python ecosystem files.

View File

@ -4,11 +4,12 @@ Package rpmdb provides a concrete Cataloger implementation for RPM "Package" DB
package rpmdb
import (
"io"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/cataloger/common"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"io"
)
// Cataloger catalogs pkg.RpmPkg Package Types defined in RPM DB files.

View File

@ -0,0 +1,34 @@
package plugin
import (
"context"
"github.com/anchore/syft/syft/cataloger"
syftPluginGrpc "github.com/anchore/syft/syft/plugin/grpc"
"github.com/anchore/syft/syft/plugin/proto"
"github.com/hashicorp/go-plugin"
"google.golang.org/grpc"
)
// integrity check
var _ plugin.GRPCPlugin = &CatalogerPlugin{}
// Cataloger is the interface exposed as a plugin.
type Cataloger interface {
cataloger.Cataloger
}
// CatalogerPlugin is the implementation of plugin.Plugin that is served/consumed.
type CatalogerPlugin struct {
plugin.NetRPCUnsupportedPlugin
Impl Cataloger
}
func (p *CatalogerPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error {
proto.RegisterCatalogerServer(s, syftPluginGrpc.NewCatalogServer(p.Impl, broker))
return nil
}
func (p *CatalogerPlugin) GRPCClient(ctx context.Context, broker *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
return syftPluginGrpc.NewCatalogerClient(proto.NewCatalogerClient(c), broker), nil
}

43
syft/plugin/discover.go Normal file
View File

@ -0,0 +1,43 @@
package plugin
import "path/filepath"
func Discover(dir string, pluginTypes ...Type) ([]Plugin, error) {
var err error
if len(pluginTypes) == 0 {
pluginTypes = AllTypes
}
if !filepath.IsAbs(dir) {
dir, err = filepath.Abs(dir)
if err != nil {
return nil, err
}
}
var plugins []Plugin
for _, pluginType := range pluginTypes {
// look into a sub dir named by the plugin type
searchDir := filepath.Join(dir, pluginType.String())
paths, err := filepath.Glob(filepath.Join(searchDir, "*"))
if err != nil {
return nil, err
}
for _, path := range paths {
// TODO: should we use a config for some of this?
plugins = append(plugins, NewPlugin(Config{
// TODO: should the name be org/name instead of just name? this implies changing the dir storage too
Name: filepath.Base(path),
Type: pluginType,
Command: path,
Args: nil, // TODO
Env: nil, // TODO
}))
}
}
return plugins, nil
}

View File

@ -0,0 +1,102 @@
package grpc
import (
"context"
"fmt"
"io"
"io/ioutil"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/plugin/proto"
"github.com/anchore/syft/syft/scope"
"github.com/hashicorp/go-plugin"
"google.golang.org/grpc"
)
type CatalogerClient struct {
broker *plugin.GRPCBroker
client proto.CatalogerClient
}
func NewCatalogerClient(client proto.CatalogerClient, broker *plugin.GRPCBroker) *CatalogerClient {
return &CatalogerClient{
broker: broker,
client: client,
}
}
func (c *CatalogerClient) Name() string {
resp, err := c.client.Name(context.Background(), &proto.Empty{})
if err != nil {
return fmt.Sprintf("error (%s)", err.Error())
}
return resp.Name
}
func (c *CatalogerClient) SelectFiles(resolver scope.FileResolver) error {
fileResolverServer := &FileResolverServer{Impl: resolver}
var s *grpc.Server
serverFunc := func(opts []grpc.ServerOption) *grpc.Server {
s = grpc.NewServer(opts...)
proto.RegisterFileResolverServer(s, fileResolverServer)
return s
}
brokerID := c.broker.NextId()
go c.broker.AcceptAndServe(brokerID, serverFunc)
_, err := c.client.SelectFiles(context.Background(), &proto.SelectFilesRequest{
FileResolverBrokerId: brokerID,
})
s.Stop()
return err
}
func (c *CatalogerClient) Catalog(contents map[file.Reference]io.Reader) ([]pkg.Package, error) {
var fileRefContents []*proto.FileReferenceContents
for ref, reader := range contents {
readerContents, err := ioutil.ReadAll(reader)
if err != nil {
return nil, fmt.Errorf("could not read %+v contents: %+v", ref, err)
}
fileRefContents = append(fileRefContents, &proto.FileReferenceContents{
Id: int64(ref.ID()),
Path: string(ref.Path),
Contents: string(readerContents),
})
}
resp, err := c.client.Catalog(context.Background(), &proto.CatalogRequest{
Contents: fileRefContents,
})
if err != nil {
return nil, err
}
var result []pkg.Package
for _, p := range resp.Package {
if p != nil {
var sources []file.Reference
for _, s := range p.Source {
sources = append(sources, file.NewFileReferenceWithID(file.Path(s.Path), uint64(s.Id)))
}
// TODO: this is potentially brittle
result = append(result, pkg.Package{
Name: p.Name,
Version: p.Version,
FoundBy: p.FoundBy,
Source: sources,
Licenses: p.Licenses,
Language: pkg.Language(p.Language),
Type: pkg.Type(p.Type),
Metadata: p.Metadata,
})
}
}
return result, nil
}

View File

@ -0,0 +1,99 @@
package grpc
import (
"context"
"io"
"strings"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/cataloger"
"github.com/anchore/syft/syft/plugin/proto"
"github.com/hashicorp/go-plugin"
)
type CatalogerServer struct {
Impl cataloger.Cataloger
broker *plugin.GRPCBroker
}
func NewCatalogServer(impl cataloger.Cataloger, broker *plugin.GRPCBroker) *CatalogerServer {
return &CatalogerServer{
Impl: impl,
broker: broker,
}
}
func (s *CatalogerServer) Name(ctx context.Context, req *proto.Empty) (*proto.NameResponse, error) {
name := s.Impl.Name()
return &proto.NameResponse{
Name: name,
}, nil
}
func (s *CatalogerServer) SelectFiles(ctx context.Context, req *proto.SelectFilesRequest) (*proto.SelectFilesResponse, error) {
conn, err := s.broker.Dial(req.FileResolverBrokerId)
if err != nil {
return nil, err
}
defer conn.Close()
fileResolverClient := &FileResolverClient{proto.NewFileResolverClient(conn)}
fileRefs := s.Impl.SelectFiles(fileResolverClient)
var refs []*proto.FileReference
for _, ref := range fileRefs {
refs = append(refs, &proto.FileReference{
Id: int64(ref.ID()),
Path: string(ref.Path),
})
}
return &proto.SelectFilesResponse{
Files: refs,
}, nil
}
func (s *CatalogerServer) Catalog(ctx context.Context, req *proto.CatalogRequest) (*proto.CatalogResponse, error) {
contents := make(map[file.Reference]io.Reader)
for _, f := range req.Contents {
contents[file.NewFileReferenceWithID(file.Path(f.Path), uint64(f.Id))] = strings.NewReader(f.Contents)
}
packages, err := s.Impl.Catalog(contents)
if err != nil {
return nil, err
}
var results []proto.Package
for _, p := range packages {
var sources []*proto.FileReference
for _, s := range p.Source {
sources = append(sources, &proto.FileReference{
Id: int64(s.ID()),
Path: string(s.Path),
})
}
var metadata map[string]string
if v, ok := p.Metadata.(map[string]string); ok {
metadata = v
}
// TODO: this is potentially brittle
results = append(results, proto.Package{
Name: p.Name,
Version: p.Version,
FoundBy: p.FoundBy,
Source: sources,
Licenses: p.Licenses,
Language: uint64(p.Language),
Type: string(p.Type),
// TODO: metadata needs to be more thoroughly thought through
Metadata: metadata,
})
}
return &proto.CatalogResponse{
Package: nil,
}, nil
}

View File

@ -0,0 +1,46 @@
package grpc
import (
"context"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/plugin/proto"
)
type FileResolverClient struct{ client proto.FileResolverClient }
func (m *FileResolverClient) FilesByPath(paths ...file.Path) ([]file.Reference, error) {
var pathStrs []string
for _, p := range paths {
pathStrs = append(pathStrs, string(p))
}
resp, err := m.client.FilesByPath(context.Background(), &proto.FileResolverRequest{
Paths: pathStrs,
})
if err != nil {
return nil, err
}
var result []file.Reference
for _, ref := range resp.Files {
result = append(result, file.NewFileReferenceWithID(file.Path(ref.Path), uint64(ref.Id)))
}
return result, err
}
func (m *FileResolverClient) FilesByGlob(patterns ...string) ([]file.Reference, error) {
resp, err := m.client.FilesByGlob(context.Background(), &proto.FileResolverRequest{
Paths: patterns,
})
if err != nil {
return nil, err
}
var result []file.Reference
for _, ref := range resp.Files {
result = append(result, file.NewFileReferenceWithID(file.Path(ref.Path), uint64(ref.Id)))
}
return result, err
}

View File

@ -0,0 +1,55 @@
package grpc
import (
"context"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/plugin/proto"
"github.com/anchore/syft/syft/scope"
)
type FileResolverServer struct {
Impl scope.FileResolver
}
func (m *FileResolverServer) FilesByPath(ctx context.Context, req *proto.FileResolverRequest) (resp *proto.FileResolverResponse, err error) {
var paths []file.Path
for _, p := range req.Paths {
paths = append(paths, file.Path(p))
}
r, err := m.Impl.FilesByPath(paths...)
if err != nil {
return nil, err
}
var refs []*proto.FileReference
for _, ref := range r {
refs = append(refs, &proto.FileReference{
Id: int64(ref.ID()),
Path: string(ref.Path),
})
}
return &proto.FileResolverResponse{
Files: refs,
}, nil
}
func (m *FileResolverServer) FilesByGlob(ctx context.Context, req *proto.FileResolverRequest) (resp *proto.FileResolverResponse, err error) {
r, err := m.Impl.FilesByGlob(req.Paths...)
if err != nil {
return nil, err
}
var refs []*proto.FileReference
for _, ref := range r {
refs = append(refs, &proto.FileReference{
Id: int64(ref.ID()),
Path: string(ref.Path),
})
}
return &proto.FileResolverResponse{
Files: refs,
}, nil
}

85
syft/plugin/plugin.go Normal file
View File

@ -0,0 +1,85 @@
package plugin
import (
"fmt"
"os/exec"
"github.com/hashicorp/go-plugin"
)
var plugins = map[int]plugin.PluginSet{
1: {
TypeCataloger.String(): &CatalogerPlugin{},
},
}
type Config struct {
Name string
Type Type
Command string
Args []string
Env []string
//Sha256 []byte
}
type Plugin struct {
Config Config
clientConfig *plugin.ClientConfig
client *plugin.Client
}
func NewPlugin(config Config) Plugin {
cmd := exec.Command(config.Command, config.Args...)
cmd.Env = append(cmd.Env, config.Env...)
//secureConfig := &plugin.SecureConfig{
// Checksum: config.Sha256,
// Hash: sha256.New(),
//}
clientConfig := &plugin.ClientConfig{
HandshakeConfig: config.Type.HandshakeConfig(),
VersionedPlugins: plugins,
//SecureConfig: secureConfig,
Cmd: cmd,
AllowedProtocols: []plugin.Protocol{
plugin.ProtocolGRPC,
},
}
return Plugin{
Config: config,
clientConfig: clientConfig,
}
}
func (p Plugin) Start() (interface{}, error) {
if p.client != nil {
return nil, fmt.Errorf("plugin already started")
}
// start the plugin in a sub process
p.client = plugin.NewClient(p.clientConfig)
// connect to the sub process via RPC
rpcClient, err := p.client.Client()
if err != nil {
return nil, err
}
// fetch the plugin object meeting the requested interface
raw, err := rpcClient.Dispense(p.Config.Type.String())
if err != nil {
return nil, err
}
return raw, nil
}
func (p Plugin) Stop() error {
if p.client == nil {
return fmt.Errorf("plugin has not been started")
}
p.client.Kill()
return nil
}

View File

@ -0,0 +1,841 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: cataloger.proto
package proto
import (
context "context"
fmt "fmt"
proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type FileReference struct {
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *FileReference) Reset() { *m = FileReference{} }
func (m *FileReference) String() string { return proto.CompactTextString(m) }
func (*FileReference) ProtoMessage() {}
func (*FileReference) Descriptor() ([]byte, []int) {
return fileDescriptor_346aaad5d7f2c092, []int{0}
}
func (m *FileReference) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FileReference.Unmarshal(m, b)
}
func (m *FileReference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_FileReference.Marshal(b, m, deterministic)
}
func (m *FileReference) XXX_Merge(src proto.Message) {
xxx_messageInfo_FileReference.Merge(m, src)
}
func (m *FileReference) XXX_Size() int {
return xxx_messageInfo_FileReference.Size(m)
}
func (m *FileReference) XXX_DiscardUnknown() {
xxx_messageInfo_FileReference.DiscardUnknown(m)
}
var xxx_messageInfo_FileReference proto.InternalMessageInfo
func (m *FileReference) GetId() int64 {
if m != nil {
return m.Id
}
return 0
}
func (m *FileReference) GetPath() string {
if m != nil {
return m.Path
}
return ""
}
type FileReferenceContents struct {
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
Contents string `protobuf:"bytes,3,opt,name=contents,proto3" json:"contents,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *FileReferenceContents) Reset() { *m = FileReferenceContents{} }
func (m *FileReferenceContents) String() string { return proto.CompactTextString(m) }
func (*FileReferenceContents) ProtoMessage() {}
func (*FileReferenceContents) Descriptor() ([]byte, []int) {
return fileDescriptor_346aaad5d7f2c092, []int{1}
}
func (m *FileReferenceContents) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FileReferenceContents.Unmarshal(m, b)
}
func (m *FileReferenceContents) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_FileReferenceContents.Marshal(b, m, deterministic)
}
func (m *FileReferenceContents) XXX_Merge(src proto.Message) {
xxx_messageInfo_FileReferenceContents.Merge(m, src)
}
func (m *FileReferenceContents) XXX_Size() int {
return xxx_messageInfo_FileReferenceContents.Size(m)
}
func (m *FileReferenceContents) XXX_DiscardUnknown() {
xxx_messageInfo_FileReferenceContents.DiscardUnknown(m)
}
var xxx_messageInfo_FileReferenceContents proto.InternalMessageInfo
func (m *FileReferenceContents) GetId() int64 {
if m != nil {
return m.Id
}
return 0
}
func (m *FileReferenceContents) GetPath() string {
if m != nil {
return m.Path
}
return ""
}
func (m *FileReferenceContents) GetContents() string {
if m != nil {
return m.Contents
}
return ""
}
type Empty struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Empty) Reset() { *m = Empty{} }
func (m *Empty) String() string { return proto.CompactTextString(m) }
func (*Empty) ProtoMessage() {}
func (*Empty) Descriptor() ([]byte, []int) {
return fileDescriptor_346aaad5d7f2c092, []int{2}
}
func (m *Empty) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Empty.Unmarshal(m, b)
}
func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Empty.Marshal(b, m, deterministic)
}
func (m *Empty) XXX_Merge(src proto.Message) {
xxx_messageInfo_Empty.Merge(m, src)
}
func (m *Empty) XXX_Size() int {
return xxx_messageInfo_Empty.Size(m)
}
func (m *Empty) XXX_DiscardUnknown() {
xxx_messageInfo_Empty.DiscardUnknown(m)
}
var xxx_messageInfo_Empty proto.InternalMessageInfo
type FileResolverRequest struct {
Paths []string `protobuf:"bytes,1,rep,name=paths,proto3" json:"paths,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *FileResolverRequest) Reset() { *m = FileResolverRequest{} }
func (m *FileResolverRequest) String() string { return proto.CompactTextString(m) }
func (*FileResolverRequest) ProtoMessage() {}
func (*FileResolverRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_346aaad5d7f2c092, []int{3}
}
func (m *FileResolverRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FileResolverRequest.Unmarshal(m, b)
}
func (m *FileResolverRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_FileResolverRequest.Marshal(b, m, deterministic)
}
func (m *FileResolverRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_FileResolverRequest.Merge(m, src)
}
func (m *FileResolverRequest) XXX_Size() int {
return xxx_messageInfo_FileResolverRequest.Size(m)
}
func (m *FileResolverRequest) XXX_DiscardUnknown() {
xxx_messageInfo_FileResolverRequest.DiscardUnknown(m)
}
var xxx_messageInfo_FileResolverRequest proto.InternalMessageInfo
func (m *FileResolverRequest) GetPaths() []string {
if m != nil {
return m.Paths
}
return nil
}
type FileResolverResponse struct {
Files []*FileReference `protobuf:"bytes,1,rep,name=files,proto3" json:"files,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *FileResolverResponse) Reset() { *m = FileResolverResponse{} }
func (m *FileResolverResponse) String() string { return proto.CompactTextString(m) }
func (*FileResolverResponse) ProtoMessage() {}
func (*FileResolverResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_346aaad5d7f2c092, []int{4}
}
func (m *FileResolverResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FileResolverResponse.Unmarshal(m, b)
}
func (m *FileResolverResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_FileResolverResponse.Marshal(b, m, deterministic)
}
func (m *FileResolverResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_FileResolverResponse.Merge(m, src)
}
func (m *FileResolverResponse) XXX_Size() int {
return xxx_messageInfo_FileResolverResponse.Size(m)
}
func (m *FileResolverResponse) XXX_DiscardUnknown() {
xxx_messageInfo_FileResolverResponse.DiscardUnknown(m)
}
var xxx_messageInfo_FileResolverResponse proto.InternalMessageInfo
func (m *FileResolverResponse) GetFiles() []*FileReference {
if m != nil {
return m.Files
}
return nil
}
type NameResponse struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *NameResponse) Reset() { *m = NameResponse{} }
func (m *NameResponse) String() string { return proto.CompactTextString(m) }
func (*NameResponse) ProtoMessage() {}
func (*NameResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_346aaad5d7f2c092, []int{5}
}
func (m *NameResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NameResponse.Unmarshal(m, b)
}
func (m *NameResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_NameResponse.Marshal(b, m, deterministic)
}
func (m *NameResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_NameResponse.Merge(m, src)
}
func (m *NameResponse) XXX_Size() int {
return xxx_messageInfo_NameResponse.Size(m)
}
func (m *NameResponse) XXX_DiscardUnknown() {
xxx_messageInfo_NameResponse.DiscardUnknown(m)
}
var xxx_messageInfo_NameResponse proto.InternalMessageInfo
func (m *NameResponse) GetName() string {
if m != nil {
return m.Name
}
return ""
}
type SelectFilesRequest struct {
FileResolverBrokerId uint32 `protobuf:"varint,1,opt,name=fileResolverBrokerId,proto3" json:"fileResolverBrokerId,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SelectFilesRequest) Reset() { *m = SelectFilesRequest{} }
func (m *SelectFilesRequest) String() string { return proto.CompactTextString(m) }
func (*SelectFilesRequest) ProtoMessage() {}
func (*SelectFilesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_346aaad5d7f2c092, []int{6}
}
func (m *SelectFilesRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SelectFilesRequest.Unmarshal(m, b)
}
func (m *SelectFilesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SelectFilesRequest.Marshal(b, m, deterministic)
}
func (m *SelectFilesRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_SelectFilesRequest.Merge(m, src)
}
func (m *SelectFilesRequest) XXX_Size() int {
return xxx_messageInfo_SelectFilesRequest.Size(m)
}
func (m *SelectFilesRequest) XXX_DiscardUnknown() {
xxx_messageInfo_SelectFilesRequest.DiscardUnknown(m)
}
var xxx_messageInfo_SelectFilesRequest proto.InternalMessageInfo
func (m *SelectFilesRequest) GetFileResolverBrokerId() uint32 {
if m != nil {
return m.FileResolverBrokerId
}
return 0
}
type SelectFilesResponse struct {
Files []*FileReference `protobuf:"bytes,1,rep,name=files,proto3" json:"files,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SelectFilesResponse) Reset() { *m = SelectFilesResponse{} }
func (m *SelectFilesResponse) String() string { return proto.CompactTextString(m) }
func (*SelectFilesResponse) ProtoMessage() {}
func (*SelectFilesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_346aaad5d7f2c092, []int{7}
}
func (m *SelectFilesResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SelectFilesResponse.Unmarshal(m, b)
}
func (m *SelectFilesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SelectFilesResponse.Marshal(b, m, deterministic)
}
func (m *SelectFilesResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_SelectFilesResponse.Merge(m, src)
}
func (m *SelectFilesResponse) XXX_Size() int {
return xxx_messageInfo_SelectFilesResponse.Size(m)
}
func (m *SelectFilesResponse) XXX_DiscardUnknown() {
xxx_messageInfo_SelectFilesResponse.DiscardUnknown(m)
}
var xxx_messageInfo_SelectFilesResponse proto.InternalMessageInfo
func (m *SelectFilesResponse) GetFiles() []*FileReference {
if m != nil {
return m.Files
}
return nil
}
type Package struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
FoundBy string `protobuf:"bytes,3,opt,name=foundBy,proto3" json:"foundBy,omitempty"`
Source []*FileReference `protobuf:"bytes,4,rep,name=source,proto3" json:"source,omitempty"`
Licenses []string `protobuf:"bytes,5,rep,name=licenses,proto3" json:"licenses,omitempty"`
Language uint64 `protobuf:"varint,6,opt,name=language,proto3" json:"language,omitempty"`
Type string `protobuf:"bytes,7,opt,name=type,proto3" json:"type,omitempty"`
Metadata map[string]string `protobuf:"bytes,8,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Package) Reset() { *m = Package{} }
func (m *Package) String() string { return proto.CompactTextString(m) }
func (*Package) ProtoMessage() {}
func (*Package) Descriptor() ([]byte, []int) {
return fileDescriptor_346aaad5d7f2c092, []int{8}
}
func (m *Package) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Package.Unmarshal(m, b)
}
func (m *Package) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Package.Marshal(b, m, deterministic)
}
func (m *Package) XXX_Merge(src proto.Message) {
xxx_messageInfo_Package.Merge(m, src)
}
func (m *Package) XXX_Size() int {
return xxx_messageInfo_Package.Size(m)
}
func (m *Package) XXX_DiscardUnknown() {
xxx_messageInfo_Package.DiscardUnknown(m)
}
var xxx_messageInfo_Package proto.InternalMessageInfo
func (m *Package) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *Package) GetVersion() string {
if m != nil {
return m.Version
}
return ""
}
func (m *Package) GetFoundBy() string {
if m != nil {
return m.FoundBy
}
return ""
}
func (m *Package) GetSource() []*FileReference {
if m != nil {
return m.Source
}
return nil
}
func (m *Package) GetLicenses() []string {
if m != nil {
return m.Licenses
}
return nil
}
func (m *Package) GetLanguage() uint64 {
if m != nil {
return m.Language
}
return 0
}
func (m *Package) GetType() string {
if m != nil {
return m.Type
}
return ""
}
func (m *Package) GetMetadata() map[string]string {
if m != nil {
return m.Metadata
}
return nil
}
type CatalogRequest struct {
Contents []*FileReferenceContents `protobuf:"bytes,1,rep,name=contents,proto3" json:"contents,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CatalogRequest) Reset() { *m = CatalogRequest{} }
func (m *CatalogRequest) String() string { return proto.CompactTextString(m) }
func (*CatalogRequest) ProtoMessage() {}
func (*CatalogRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_346aaad5d7f2c092, []int{9}
}
func (m *CatalogRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CatalogRequest.Unmarshal(m, b)
}
func (m *CatalogRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CatalogRequest.Marshal(b, m, deterministic)
}
func (m *CatalogRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_CatalogRequest.Merge(m, src)
}
func (m *CatalogRequest) XXX_Size() int {
return xxx_messageInfo_CatalogRequest.Size(m)
}
func (m *CatalogRequest) XXX_DiscardUnknown() {
xxx_messageInfo_CatalogRequest.DiscardUnknown(m)
}
var xxx_messageInfo_CatalogRequest proto.InternalMessageInfo
func (m *CatalogRequest) GetContents() []*FileReferenceContents {
if m != nil {
return m.Contents
}
return nil
}
type CatalogResponse struct {
Package []*Package `protobuf:"bytes,1,rep,name=package,proto3" json:"package,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CatalogResponse) Reset() { *m = CatalogResponse{} }
func (m *CatalogResponse) String() string { return proto.CompactTextString(m) }
func (*CatalogResponse) ProtoMessage() {}
func (*CatalogResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_346aaad5d7f2c092, []int{10}
}
func (m *CatalogResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CatalogResponse.Unmarshal(m, b)
}
func (m *CatalogResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CatalogResponse.Marshal(b, m, deterministic)
}
func (m *CatalogResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_CatalogResponse.Merge(m, src)
}
func (m *CatalogResponse) XXX_Size() int {
return xxx_messageInfo_CatalogResponse.Size(m)
}
func (m *CatalogResponse) XXX_DiscardUnknown() {
xxx_messageInfo_CatalogResponse.DiscardUnknown(m)
}
var xxx_messageInfo_CatalogResponse proto.InternalMessageInfo
func (m *CatalogResponse) GetPackage() []*Package {
if m != nil {
return m.Package
}
return nil
}
func init() {
proto.RegisterType((*FileReference)(nil), "proto.FileReference")
proto.RegisterType((*FileReferenceContents)(nil), "proto.FileReferenceContents")
proto.RegisterType((*Empty)(nil), "proto.Empty")
proto.RegisterType((*FileResolverRequest)(nil), "proto.FileResolverRequest")
proto.RegisterType((*FileResolverResponse)(nil), "proto.FileResolverResponse")
proto.RegisterType((*NameResponse)(nil), "proto.NameResponse")
proto.RegisterType((*SelectFilesRequest)(nil), "proto.SelectFilesRequest")
proto.RegisterType((*SelectFilesResponse)(nil), "proto.SelectFilesResponse")
proto.RegisterType((*Package)(nil), "proto.Package")
proto.RegisterMapType((map[string]string)(nil), "proto.Package.MetadataEntry")
proto.RegisterType((*CatalogRequest)(nil), "proto.CatalogRequest")
proto.RegisterType((*CatalogResponse)(nil), "proto.CatalogResponse")
}
func init() { proto.RegisterFile("cataloger.proto", fileDescriptor_346aaad5d7f2c092) }
var fileDescriptor_346aaad5d7f2c092 = []byte{
// 541 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xcb, 0x8e, 0xd3, 0x3c,
0x14, 0x56, 0x7a, 0x4b, 0x7b, 0x7a, 0x99, 0x5f, 0x6e, 0xe7, 0x57, 0x08, 0x2c, 0xaa, 0xac, 0xca,
0x45, 0x5d, 0x74, 0x36, 0x15, 0xb3, 0xa2, 0x65, 0x86, 0x8b, 0x04, 0x1a, 0x99, 0x05, 0x6b, 0x4f,
0x7a, 0x5a, 0xa2, 0xa6, 0x71, 0x88, 0xdd, 0x4a, 0x79, 0x19, 0x1e, 0x83, 0x07, 0xe0, 0xc9, 0x50,
0x6c, 0x27, 0xd4, 0x10, 0x21, 0x34, 0xab, 0xf8, 0xe4, 0xfb, 0xfc, 0x9d, 0xcf, 0xe7, 0x02, 0x17,
0x21, 0x93, 0x2c, 0xe6, 0x3b, 0xcc, 0xe6, 0x69, 0xc6, 0x25, 0x27, 0x6d, 0xf5, 0x09, 0xae, 0x60,
0x78, 0x1b, 0xc5, 0x48, 0x71, 0x8b, 0x19, 0x26, 0x21, 0x92, 0x11, 0x34, 0xa2, 0x8d, 0xe7, 0x4c,
0x9d, 0x59, 0x93, 0x36, 0xa2, 0x0d, 0x21, 0xd0, 0x4a, 0x99, 0xfc, 0xe2, 0x35, 0xa6, 0xce, 0xac,
0x47, 0xd5, 0x39, 0xf8, 0x0c, 0x97, 0xd6, 0xa5, 0x35, 0x4f, 0x24, 0x26, 0x52, 0xfc, 0xcb, 0x65,
0xe2, 0x43, 0x37, 0x34, 0x7c, 0xaf, 0xa9, 0xfe, 0x57, 0x71, 0xe0, 0x42, 0xfb, 0xe6, 0x90, 0xca,
0x3c, 0x78, 0x0e, 0x63, 0x9d, 0x41, 0xf0, 0xf8, 0x84, 0x19, 0xc5, 0xaf, 0x47, 0x14, 0x92, 0x4c,
0xa0, 0x5d, 0x68, 0x08, 0xcf, 0x99, 0x36, 0x67, 0x3d, 0xaa, 0x83, 0x60, 0x05, 0x13, 0x9b, 0x2c,
0x52, 0x9e, 0x08, 0x24, 0xcf, 0xa0, 0xbd, 0x8d, 0x62, 0xd4, 0xec, 0xfe, 0x62, 0xa2, 0x5f, 0x3e,
0xb7, 0xac, 0x53, 0x4d, 0x09, 0x02, 0x18, 0x7c, 0x64, 0x07, 0xac, 0xee, 0x12, 0x68, 0x25, 0xec,
0x80, 0xea, 0x2d, 0x3d, 0xaa, 0xce, 0xc1, 0x5b, 0x20, 0x9f, 0x30, 0xc6, 0x50, 0x16, 0x0a, 0xa2,
0xf4, 0xb4, 0x80, 0xc9, 0xf6, 0x2c, 0xfb, 0x2a, 0xe3, 0x7b, 0xcc, 0xde, 0xe9, 0x2a, 0x0c, 0x69,
0x2d, 0x16, 0xbc, 0x82, 0xb1, 0xa5, 0xf4, 0x00, 0xc3, 0x3f, 0x1a, 0xe0, 0xde, 0xb1, 0x70, 0xcf,
0x76, 0xb5, 0x66, 0x89, 0x07, 0xee, 0x09, 0x33, 0x11, 0xf1, 0xc4, 0x54, 0xbf, 0x0c, 0x0b, 0x64,
0xcb, 0x8f, 0xc9, 0x66, 0x95, 0x9b, 0xfa, 0x97, 0x21, 0x79, 0x01, 0x1d, 0xc1, 0x8f, 0x59, 0x88,
0x5e, 0xeb, 0x2f, 0x06, 0x0c, 0xa7, 0x68, 0x64, 0x1c, 0x85, 0x98, 0x08, 0x14, 0x5e, 0x5b, 0xf5,
0xa3, 0x8a, 0x15, 0xc6, 0x92, 0xdd, 0x91, 0xed, 0xd0, 0xeb, 0x4c, 0x9d, 0x59, 0x8b, 0x56, 0x71,
0xe1, 0x56, 0xe6, 0x29, 0x7a, 0xae, 0x76, 0x5b, 0x9c, 0xc9, 0x12, 0xba, 0x07, 0x94, 0x6c, 0xc3,
0x24, 0xf3, 0xba, 0x2a, 0xf7, 0x13, 0x93, 0xdb, 0xbc, 0x71, 0xfe, 0xc1, 0xc0, 0x37, 0x89, 0xcc,
0x72, 0x5a, 0xb1, 0xfd, 0x6b, 0x18, 0x5a, 0x10, 0xf9, 0x0f, 0x9a, 0x7b, 0xcc, 0x4d, 0x2d, 0x8a,
0x63, 0x31, 0x35, 0x27, 0x16, 0x1f, 0xd1, 0x14, 0x42, 0x07, 0x2f, 0x1b, 0x4b, 0x27, 0x78, 0x0f,
0xa3, 0xb5, 0xde, 0x8b, 0xb2, 0x9b, 0xcb, 0xb3, 0xe9, 0x74, 0x2c, 0x23, 0xb5, 0x13, 0x7f, 0x36,
0xbb, 0xd7, 0x70, 0x51, 0x69, 0x99, 0x7e, 0xce, 0xc0, 0x4d, 0xb5, 0x7d, 0xa3, 0x35, 0xb2, 0x1f,
0x45, 0x4b, 0x78, 0xf1, 0xdd, 0x81, 0xde, 0xba, 0xdc, 0x50, 0xf2, 0x14, 0x5a, 0xc5, 0x30, 0x92,
0x81, 0xa1, 0xab, 0x9d, 0xf0, 0xc7, 0x26, 0xb2, 0xe6, 0xf4, 0x35, 0xf4, 0xcf, 0x26, 0x89, 0x3c,
0x32, 0x9c, 0x3f, 0xe7, 0xd4, 0xf7, 0xeb, 0x20, 0xa3, 0xb2, 0x04, 0xd7, 0x64, 0x27, 0x97, 0x86,
0x66, 0xd7, 0xc5, 0xff, 0xff, 0xf7, 0xdf, 0xfa, 0xe6, 0xe2, 0x9b, 0x03, 0x83, 0xf3, 0xe5, 0x23,
0xb7, 0xd0, 0x57, 0xda, 0xab, 0xfc, 0x4e, 0x6d, 0xbb, 0x55, 0x3d, 0x6b, 0x9b, 0xfd, 0xc7, 0xb5,
0x98, 0xb1, 0xf4, 0x4b, 0xe7, 0x4d, 0xcc, 0xef, 0x1f, 0xac, 0x73, 0xdf, 0x51, 0xd8, 0xd5, 0xcf,
0x00, 0x00, 0x00, 0xff, 0xff, 0x6e, 0xfe, 0x04, 0x3e, 0x01, 0x05, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6
// CatalogerClient is the client API for Cataloger service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type CatalogerClient interface {
Name(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*NameResponse, error)
SelectFiles(ctx context.Context, in *SelectFilesRequest, opts ...grpc.CallOption) (*SelectFilesResponse, error)
Catalog(ctx context.Context, in *CatalogRequest, opts ...grpc.CallOption) (*CatalogResponse, error)
}
type catalogerClient struct {
cc grpc.ClientConnInterface
}
func NewCatalogerClient(cc grpc.ClientConnInterface) CatalogerClient {
return &catalogerClient{cc}
}
func (c *catalogerClient) Name(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*NameResponse, error) {
out := new(NameResponse)
err := c.cc.Invoke(ctx, "/proto.Cataloger/Name", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *catalogerClient) SelectFiles(ctx context.Context, in *SelectFilesRequest, opts ...grpc.CallOption) (*SelectFilesResponse, error) {
out := new(SelectFilesResponse)
err := c.cc.Invoke(ctx, "/proto.Cataloger/SelectFiles", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *catalogerClient) Catalog(ctx context.Context, in *CatalogRequest, opts ...grpc.CallOption) (*CatalogResponse, error) {
out := new(CatalogResponse)
err := c.cc.Invoke(ctx, "/proto.Cataloger/Catalog", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// CatalogerServer is the server API for Cataloger service.
type CatalogerServer interface {
Name(context.Context, *Empty) (*NameResponse, error)
SelectFiles(context.Context, *SelectFilesRequest) (*SelectFilesResponse, error)
Catalog(context.Context, *CatalogRequest) (*CatalogResponse, error)
}
// UnimplementedCatalogerServer can be embedded to have forward compatible implementations.
type UnimplementedCatalogerServer struct {
}
func (*UnimplementedCatalogerServer) Name(ctx context.Context, req *Empty) (*NameResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Name not implemented")
}
func (*UnimplementedCatalogerServer) SelectFiles(ctx context.Context, req *SelectFilesRequest) (*SelectFilesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method SelectFiles not implemented")
}
func (*UnimplementedCatalogerServer) Catalog(ctx context.Context, req *CatalogRequest) (*CatalogResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Catalog not implemented")
}
func RegisterCatalogerServer(s *grpc.Server, srv CatalogerServer) {
s.RegisterService(&_Cataloger_serviceDesc, srv)
}
func _Cataloger_Name_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CatalogerServer).Name(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/proto.Cataloger/Name",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CatalogerServer).Name(ctx, req.(*Empty))
}
return interceptor(ctx, in, info, handler)
}
func _Cataloger_SelectFiles_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SelectFilesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CatalogerServer).SelectFiles(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/proto.Cataloger/SelectFiles",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CatalogerServer).SelectFiles(ctx, req.(*SelectFilesRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Cataloger_Catalog_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CatalogRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CatalogerServer).Catalog(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/proto.Cataloger/Catalog",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CatalogerServer).Catalog(ctx, req.(*CatalogRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Cataloger_serviceDesc = grpc.ServiceDesc{
ServiceName: "proto.Cataloger",
HandlerType: (*CatalogerServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Name",
Handler: _Cataloger_Name_Handler,
},
{
MethodName: "SelectFiles",
Handler: _Cataloger_SelectFiles_Handler,
},
{
MethodName: "Catalog",
Handler: _Cataloger_Catalog_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cataloger.proto",
}
// FileResolverClient is the client API for FileResolver service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type FileResolverClient interface {
FilesByPath(ctx context.Context, in *FileResolverRequest, opts ...grpc.CallOption) (*FileResolverResponse, error)
FilesByGlob(ctx context.Context, in *FileResolverRequest, opts ...grpc.CallOption) (*FileResolverResponse, error)
}
type fileResolverClient struct {
cc grpc.ClientConnInterface
}
func NewFileResolverClient(cc grpc.ClientConnInterface) FileResolverClient {
return &fileResolverClient{cc}
}
func (c *fileResolverClient) FilesByPath(ctx context.Context, in *FileResolverRequest, opts ...grpc.CallOption) (*FileResolverResponse, error) {
out := new(FileResolverResponse)
err := c.cc.Invoke(ctx, "/proto.FileResolver/FilesByPath", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *fileResolverClient) FilesByGlob(ctx context.Context, in *FileResolverRequest, opts ...grpc.CallOption) (*FileResolverResponse, error) {
out := new(FileResolverResponse)
err := c.cc.Invoke(ctx, "/proto.FileResolver/FilesByGlob", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// FileResolverServer is the server API for FileResolver service.
type FileResolverServer interface {
FilesByPath(context.Context, *FileResolverRequest) (*FileResolverResponse, error)
FilesByGlob(context.Context, *FileResolverRequest) (*FileResolverResponse, error)
}
// UnimplementedFileResolverServer can be embedded to have forward compatible implementations.
type UnimplementedFileResolverServer struct {
}
func (*UnimplementedFileResolverServer) FilesByPath(ctx context.Context, req *FileResolverRequest) (*FileResolverResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method FilesByPath not implemented")
}
func (*UnimplementedFileResolverServer) FilesByGlob(ctx context.Context, req *FileResolverRequest) (*FileResolverResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method FilesByGlob not implemented")
}
func RegisterFileResolverServer(s *grpc.Server, srv FileResolverServer) {
s.RegisterService(&_FileResolver_serviceDesc, srv)
}
func _FileResolver_FilesByPath_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(FileResolverRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(FileResolverServer).FilesByPath(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/proto.FileResolver/FilesByPath",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(FileResolverServer).FilesByPath(ctx, req.(*FileResolverRequest))
}
return interceptor(ctx, in, info, handler)
}
func _FileResolver_FilesByGlob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(FileResolverRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(FileResolverServer).FilesByGlob(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/proto.FileResolver/FilesByGlob",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(FileResolverServer).FilesByGlob(ctx, req.(*FileResolverRequest))
}
return interceptor(ctx, in, info, handler)
}
var _FileResolver_serviceDesc = grpc.ServiceDesc{
ServiceName: "proto.FileResolver",
HandlerType: (*FileResolverServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "FilesByPath",
Handler: _FileResolver_FilesByPath_Handler,
},
{
MethodName: "FilesByGlob",
Handler: _FileResolver_FilesByGlob_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cataloger.proto",
}

View File

@ -0,0 +1,67 @@
syntax = "proto3";
package proto;
message FileReference {
int64 id = 1;
string path = 2;
}
message FileReferenceContents {
int64 id = 1;
string path = 2;
string contents = 3;
}
message Empty {
}
message FileResolverRequest {
repeated string paths = 1;
}
message FileResolverResponse {
repeated FileReference files = 1;
}
message NameResponse {
string name = 1;
}
message SelectFilesRequest {
uint32 fileResolverBrokerId = 1;
}
message SelectFilesResponse {
repeated FileReference files = 1;
}
message Package {
string name = 1;
string version = 2;
string foundBy = 3;
repeated FileReference source = 4;
repeated string licenses = 5;
uint64 language = 6;
string type = 7;
map<string, string> metadata = 8;
}
message CatalogRequest {
repeated FileReferenceContents contents = 1;
}
message CatalogResponse {
repeated Package package = 1;
}
service Cataloger {
rpc Name(Empty) returns (NameResponse);
rpc SelectFiles(SelectFilesRequest) returns (SelectFilesResponse);
rpc Catalog(CatalogRequest) returns (CatalogResponse);
}
service FileResolver {
rpc FilesByPath(FileResolverRequest) returns (FileResolverResponse);
rpc FilesByGlob(FileResolverRequest) returns (FileResolverResponse);
}

49
syft/plugin/type.go Normal file
View File

@ -0,0 +1,49 @@
package plugin
import (
"fmt"
"github.com/hashicorp/go-plugin"
)
var AllTypes = []Type{
TypeCataloger,
}
type Type uint64
const (
TypeUnknown Type = iota
TypeCataloger
)
func (p Type) String() string {
switch p {
case TypeCataloger:
return "cataloger"
default:
return "unknown"
}
}
func (p Type) HandshakeConfig() plugin.HandshakeConfig {
switch p {
case TypeCataloger:
return plugin.HandshakeConfig{
ProtocolVersion: 1,
MagicCookieKey: "SYFT_CATALOGER_PLUGIN",
MagicCookieValue: "0f86cc7f-6f97-410e-a844-087cd12e36e3",
}
default:
panic(fmt.Errorf("plugin type unsupported"))
}
}
func ParseType(pluginType string) Type {
switch pluginType {
case "cataloger":
return TypeCataloger
default:
return TypeUnknown
}
}

View File

@ -2,12 +2,13 @@ package resolvers
import (
"fmt"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/internal/log"
"github.com/bmatcuk/doublestar"
"io"
"os"
"path"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/internal/log"
"github.com/bmatcuk/doublestar"
)
// DirectoryResolver implements path and content access for the directory data source.