Skip to content

Commit

Permalink
feat(server): add internal --path-prefix flag for client/server mode (
Browse files Browse the repository at this point in the history
#7321)

Signed-off-by: knqyf263 <[email protected]>
  • Loading branch information
knqyf263 authored Aug 21, 2024
1 parent 3f0e7eb commit 24a4563
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 77 deletions.
15 changes: 0 additions & 15 deletions docs/docs/references/configuration/config-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ cache:
# Same as '--cache-backend'
backend: "fs"

# Same as '--clear-cache'
clear: false

redis:
# Same as '--redis-ca'
ca: ""
Expand Down Expand Up @@ -112,9 +109,6 @@ db:
# Same as '--skip-java-db-update'
java-skip-update: false

# Same as '--light'
light: false

# Same as '--no-progress'
no-progress: false

Expand All @@ -124,9 +118,6 @@ db:
# Same as '--skip-db-update'
skip-update: false

# Same as '--reset'
reset: false

```
## Image options

Expand Down Expand Up @@ -411,9 +402,6 @@ misconfiguration:
# Same as '--include-non-failures'
include-non-failures: false

# Same as '--reset-checks-bundle'
reset-checks-bundle: false

# Same as '--misconfig-scanners'
scanners:
- azure-arm
Expand Down Expand Up @@ -580,9 +568,6 @@ scan:
# Same as '--skip-files'
skip-files: []

# Same as '--slow'
slow: false

```
## Secret options

Expand Down
59 changes: 39 additions & 20 deletions integration/client_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type csArgs struct {
Input string
ClientToken string
ClientTokenHeader string
PathPrefix string
ListAllPackages bool
Target string
secretConfig string
Expand Down Expand Up @@ -443,19 +444,24 @@ func TestClientServerWithCycloneDX(t *testing.T) {
}
}

func TestClientServerWithToken(t *testing.T) {
func TestClientServerWithCustomOptions(t *testing.T) {
token := "token"
tokenHeader := "Trivy-Token"
pathPrefix := "prefix"

tests := []struct {
name string
args csArgs
golden string
wantErr string
}{
{
name: "alpine 3.9 with token",
name: "alpine 3.9 with token and prefix",
args: csArgs{
Input: "testdata/fixtures/images/alpine-39.tar.gz",
ClientToken: "token",
ClientTokenHeader: "Trivy-Token",
ClientToken: token,
ClientTokenHeader: tokenHeader,
PathPrefix: pathPrefix,
},
golden: "testdata/alpine-39.json.golden",
},
Expand All @@ -464,26 +470,37 @@ func TestClientServerWithToken(t *testing.T) {
args: csArgs{
Input: "testdata/fixtures/images/distroless-base.tar.gz",
ClientToken: "invalidtoken",
ClientTokenHeader: "Trivy-Token",
ClientTokenHeader: tokenHeader,
PathPrefix: pathPrefix,
},
wantErr: "twirp error unauthenticated: invalid token",
},
{
name: "invalid token header",
args: csArgs{
Input: "testdata/fixtures/images/distroless-base.tar.gz",
ClientToken: "token",
ClientToken: token,
ClientTokenHeader: "Unknown-Header",
PathPrefix: pathPrefix,
},
wantErr: "twirp error unauthenticated: invalid token",
},
{
name: "wrong path prefix",
args: csArgs{
Input: "testdata/fixtures/images/distroless-base.tar.gz",
ClientToken: token,
ClientTokenHeader: tokenHeader,
PathPrefix: "wrong",
},
wantErr: "HTTP status code 404",
},
}

serverToken := "token"
serverTokenHeader := "Trivy-Token"
addr, cacheDir := setup(t, setupOptions{
token: serverToken,
tokenHeader: serverTokenHeader,
token: token,
tokenHeader: tokenHeader,
pathPrefix: pathPrefix,
})

for _, tt := range tests {
Expand Down Expand Up @@ -539,6 +556,7 @@ func TestClientServerWithRedis(t *testing.T) {
type setupOptions struct {
token string
tokenHeader string
pathPrefix string
cacheBackend string
}

Expand All @@ -556,7 +574,7 @@ func setup(t *testing.T, options setupOptions) (string, string) {
addr := fmt.Sprintf("localhost:%d", port)

go func() {
osArgs := setupServer(addr, options.token, options.tokenHeader, cacheDir, options.cacheBackend)
osArgs := setupServer(addr, options.token, options.tokenHeader, options.pathPrefix, cacheDir, options.cacheBackend)

// Run Trivy server
require.NoError(t, execute(osArgs))
Expand All @@ -569,22 +587,20 @@ func setup(t *testing.T, options setupOptions) (string, string) {
return addr, cacheDir
}

func setupServer(addr, token, tokenHeader, cacheDir, cacheBackend string) []string {
func setupServer(addr, token, tokenHeader, pathPrefix, cacheDir, cacheBackend string) []string {
osArgs := []string{
"--cache-dir",
cacheDir,
"server",
"--skip-update",
"--skip-db-update",
"--listen",
addr,
}
if token != "" {
osArgs = append(osArgs, []string{
"--token",
token,
"--token-header",
tokenHeader,
}...)
osArgs = append(osArgs, "--token", token, "--token-header", tokenHeader)
}
if pathPrefix != "" {
osArgs = append(osArgs, "--path-prefix", pathPrefix)
}
if cacheBackend != "" {
osArgs = append(osArgs, "--cache-backend", cacheBackend)
Expand All @@ -593,13 +609,13 @@ func setupServer(addr, token, tokenHeader, cacheDir, cacheBackend string) []stri
}

func setupClient(t *testing.T, c csArgs, addr string, cacheDir string) []string {
t.Helper()
if c.Command == "" {
c.Command = "image"
}
if c.RemoteAddrOption == "" {
c.RemoteAddrOption = "--server"
}
t.Helper()
osArgs := []string{
"--cache-dir",
cacheDir,
Expand Down Expand Up @@ -639,6 +655,9 @@ func setupClient(t *testing.T, c csArgs, addr string, cacheDir string) []string
if c.ClientToken != "" {
osArgs = append(osArgs, "--token", c.ClientToken, "--token-header", c.ClientTokenHeader)
}
if c.PathPrefix != "" {
osArgs = append(osArgs, "--path-prefix", c.PathPrefix)
}
if c.Input != "" {
osArgs = append(osArgs, "--input", c.Input)
}
Expand Down
2 changes: 1 addition & 1 deletion magefiles/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func writeFlags(group flag.FlagGroup, w *os.File) {

var lastParts []string
for _, flg := range flags {
if flg.GetConfigName() == "" {
if flg.GetConfigName() == "" || flg.Hidden() {
continue
}
// We need to split the config name on `.` to make the indentations needed in yaml.
Expand Down
9 changes: 8 additions & 1 deletion pkg/cache/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/tls"
"net/http"

"github.com/twitchtv/twirp"
"golang.org/x/xerrors"

"github.com/aquasecurity/trivy/pkg/fanal/types"
Expand All @@ -19,6 +20,7 @@ type RemoteOptions struct {
ServerAddr string
CustomHeaders http.Header
Insecure bool
PathPrefix string
}

// RemoteCache implements remote cache
Expand All @@ -39,7 +41,12 @@ func NewRemoteCache(opts RemoteOptions) *RemoteCache {
},
},
}
c := rpcCache.NewCacheProtobufClient(opts.ServerAddr, httpClient)

var twirpOpts []twirp.ClientOption
if opts.PathPrefix != "" {
twirpOpts = append(twirpOpts, twirp.WithClientPathPrefix(opts.PathPrefix))
}
c := rpcCache.NewCacheProtobufClient(opts.ServerAddr, httpClient, twirpOpts...)
return &RemoteCache{
ctx: ctx,
client: c,
Expand Down
6 changes: 1 addition & 5 deletions pkg/commands/artifact/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -545,11 +545,7 @@ func (r *runner) initScannerConfig(opts flag.Options) (ScannerConfig, types.Scan
Target: target,
CacheOptions: opts.CacheOpts(),
RemoteCacheOptions: opts.RemoteCacheOpts(),
ServerOption: client.ScannerOption{
RemoteURL: opts.ServerAddr,
CustomHeaders: opts.CustomHeaders,
Insecure: opts.Insecure,
},
ServerOption: opts.ClientScannerOpts(),
ArtifactOption: artifact.Option{
DisabledAnalyzers: disabledAnalyzers(opts),
DisabledHandlers: disabledHandlers,
Expand Down
2 changes: 1 addition & 1 deletion pkg/commands/server/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ func Run(ctx context.Context, opts flag.Options) (err error) {
m.Register()

server := rpcServer.NewServer(opts.AppVersion, opts.Listen, opts.CacheDir, opts.Token, opts.TokenHeader,
opts.DBRepository, opts.RegistryOpts())
opts.PathPrefix, opts.DBRepository, opts.RegistryOpts())
return server.ListenAndServe(ctx, cacheClient, opts.SkipDBUpdate)
}
30 changes: 26 additions & 4 deletions pkg/flag/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/plugin"
"github.com/aquasecurity/trivy/pkg/result"
"github.com/aquasecurity/trivy/pkg/rpc/client"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/version/app"
)
Expand Down Expand Up @@ -56,15 +57,21 @@ type Flag[T FlagType] struct {
// Usage explains how to use the flag.
Usage string

// Persistent represents if the flag is persistent
// Persistent represents if the flag is persistent.
Persistent bool

// Deprecated represents if the flag is deprecated
// Deprecated represents if the flag is deprecated.
// It shows a warning message when the flag is used.
Deprecated string

// Removed represents if the flag is removed and no longer works
// Removed represents if the flag is removed and no longer works.
// It shows an error message when the flag is used.
Removed string

// Internal represents if the flag is for internal use only.
// It is not shown in the usage message.
Internal bool

// Aliases represents aliases
Aliases []Alias

Expand Down Expand Up @@ -208,6 +215,10 @@ func (f *Flag[T]) GetAliases() []Alias {
return f.Aliases
}

func (f *Flag[T]) Hidden() bool {
return f.Deprecated != "" || f.Removed != "" || f.Internal
}

func (f *Flag[T]) Value() (t T) {
if f == nil {
return t
Expand Down Expand Up @@ -249,7 +260,7 @@ func (f *Flag[T]) Add(cmd *cobra.Command) {
flags.Float64P(f.Name, f.Shorthand, v, f.Usage)
}

if f.Deprecated != "" || f.Removed != "" {
if f.Hidden() {
_ = flags.MarkHidden(f.Name)
}
}
Expand Down Expand Up @@ -313,6 +324,7 @@ type Flagger interface {
GetConfigName() string
GetDefaultValue() any
GetAliases() []Alias
Hidden() bool

Parse() error
Add(cmd *cobra.Command)
Expand Down Expand Up @@ -480,6 +492,16 @@ func (o *Options) RemoteCacheOpts() cache.RemoteOptions {
ServerAddr: o.ServerAddr,
CustomHeaders: o.CustomHeaders,
Insecure: o.Insecure,
PathPrefix: o.PathPrefix,
}
}

func (o *Options) ClientScannerOpts() client.ScannerOption {
return client.ScannerOption{
RemoteURL: o.ServerAddr,
CustomHeaders: o.CustomHeaders,
Insecure: o.Insecure,
PathPrefix: o.PathPrefix,
}
}

Expand Down
Loading

0 comments on commit 24a4563

Please sign in to comment.