Files
trivy/pkg/flag/remote_flags.go
Teppei Fukuda aca11b95d0 refactor: add allowed values for CLI flags (#4800)
* refactor: rename Value to Default

* refactor: support allowed values for CLI flags

* docs: auto-generate

* test: fix

* test: add tests for flags
2023-07-17 13:13:23 +00:00

143 lines
3.2 KiB
Go

package flag
import (
"net/http"
"strings"
"github.com/aquasecurity/trivy/pkg/log"
)
const (
DefaultTokenHeader = "Trivy-Token"
)
var (
ServerTokenFlag = Flag{
Name: "token",
ConfigName: "server.token",
Default: "",
Usage: "for authentication in client/server mode",
}
ServerTokenHeaderFlag = Flag{
Name: "token-header",
ConfigName: "server.token-header",
Default: DefaultTokenHeader,
Usage: "specify a header name for token in client/server mode",
}
ServerAddrFlag = Flag{
Name: "server",
ConfigName: "server.addr",
Default: "",
Usage: "server address in client mode",
}
ServerCustomHeadersFlag = Flag{
Name: "custom-headers",
ConfigName: "server.custom-headers",
Default: []string{},
Usage: "custom headers in client mode",
}
ServerListenFlag = Flag{
Name: "listen",
ConfigName: "server.listen",
Default: "localhost:4954",
Usage: "listen address in server mode",
}
)
// RemoteFlagGroup composes common printer flag structs
// used for commands requiring reporting logic.
type RemoteFlagGroup struct {
// for client/server
Token *Flag
TokenHeader *Flag
// for client
ServerAddr *Flag
CustomHeaders *Flag
// for server
Listen *Flag
}
type RemoteOptions struct {
Token string
TokenHeader string
ServerAddr string
Listen string
CustomHeaders http.Header
}
func NewClientFlags() *RemoteFlagGroup {
return &RemoteFlagGroup{
Token: &ServerTokenFlag,
TokenHeader: &ServerTokenHeaderFlag,
ServerAddr: &ServerAddrFlag,
CustomHeaders: &ServerCustomHeadersFlag,
}
}
func NewServerFlags() *RemoteFlagGroup {
return &RemoteFlagGroup{
Token: &ServerTokenFlag,
TokenHeader: &ServerTokenHeaderFlag,
Listen: &ServerListenFlag,
}
}
func (f *RemoteFlagGroup) Name() string {
return "Client/Server"
}
func (f *RemoteFlagGroup) Flags() []*Flag {
return []*Flag{f.Token, f.TokenHeader, f.ServerAddr, f.CustomHeaders, f.Listen}
}
func (f *RemoteFlagGroup) ToOptions() RemoteOptions {
serverAddr := getString(f.ServerAddr)
customHeaders := splitCustomHeaders(getStringSlice(f.CustomHeaders))
listen := getString(f.Listen)
token := getString(f.Token)
tokenHeader := getString(f.TokenHeader)
if serverAddr == "" && listen == "" {
switch {
case len(customHeaders) > 0:
log.Logger.Warn(`"--custom-header" can be used only with "--server"`)
case token != "":
log.Logger.Warn(`"--token" can be used only with "--server"`)
case tokenHeader != "" && tokenHeader != DefaultTokenHeader:
log.Logger.Warn(`"--token-header" can be used only with "--server"`)
}
}
if token == "" && tokenHeader != DefaultTokenHeader {
log.Logger.Warn(`"--token-header" should be used with "--token"`)
}
if token != "" && tokenHeader != "" {
customHeaders.Set(tokenHeader, token)
}
return RemoteOptions{
Token: token,
TokenHeader: tokenHeader,
ServerAddr: serverAddr,
CustomHeaders: customHeaders,
Listen: listen,
}
}
func splitCustomHeaders(headers []string) http.Header {
result := make(http.Header)
for _, header := range headers {
// e.g. x-api-token:XXX
s := strings.SplitN(header, ":", 2)
if len(s) != 2 {
continue
}
result.Set(s[0], s[1])
}
return result
}